3

我目前正在重构我的应用程序以确保它符合 MVC。我想拆分控制器(扩展 UIController 的 MyController)和视图(扩展 UIView 的 HomeView)我在 myController 中使用

self.view = [[HomeView alloc] init];

当我按下 UIButton 时,会在视图中调用一个方法,在这个方法中我想从控制器调用一个方法。

在我看来

[zenModeBtn addTarget:self action:@selector(touchZenMode:) forControlEvents:UIControlEventTouchDown];

...

- (void) touchZenMode:(id) sender {
   [myController playZenMode];
}

但是在视图中引用控制器确实是一种不好的做法,不是吗?

编辑 :

所以在我的 UIViewController 我做了这个:

- (id) init {
    HomeView* myHomeView = [[HomeView alloc] init];
    [myHomeView.arcadeModeBtn addTarget:self action:@selector(touchArcadeMode) forControlEvents:UIControlEventTouchUpInside];
    self.view = myHomeView;
    return self;
}

那是对的吗 ?

4

4 回答 4

6

正如这里的一些答案所概述的,与您的控制器交谈的视图没有问题。例如,文本字段可以通过定义的委托方法通知其控制器。

但是,您的设计仍然存在严重缺陷。您的视图完全没有处理按钮按下本身的事务。您认为视图不应该知道其控制器的直觉是正确的。

您的控制器应该知道按钮以及如何对被点击做出反应。这就是为什么控制器有 buttonIBOutlet来告诉按钮例如更改其标题或启用状态的原因。它有按钮处理程序来响应 UI 事件。处理这个逻辑是控制器的工作。显示标题、灰显或将点击事件发送回控制器是视图的工作。

您应该放入视图中的唯一代码基本上是如何绘制自身。控制器无法处理的一切。

于 2013-04-04T01:41:14.653 回答
4

Cocoa Touch 中使用的 MVC 模式的基本思想:

可可版本的 MVC 作为复合设计模式

如此处所述:模型-视图-控制器设计模式

您想要实现的是一种松散的,甚至可能是盲目的耦合形式。通过使用协议(用于委托机制),aView只知道有一个采用特定协议的对象,它可以与之“对话”。

举个UITableView例子。它不需要知道是否有某种类型UIViewController可以帮助它收集数据,而只需要知道有一个对象采用UITableViewDatasourceDelegateand/or UITableViewDelegate; 该对象可以是任何类型。

在您的编辑中,您使用目标-动作机制,这是实现松散耦合的另一种方式。您在运行时设置连接;你的视图不知道你的控制器。因此:正确,除了@Mundi 关于您的init实施不完整的评论。

于 2013-04-04T09:13:26.090 回答
0

视图需要某种方式将事情传回控制器,向它询问下一步要做什么等问题。因此,视图了解控制器的某些信息是非常好的。

一些内置视图,如 UITextField,定义了它们用来告诉委托人正在发生的事情或要求它做某事的协议。您通常在控制器中实现协议。这样,视图对控制器的了解并不多,仅足以进行通信。这使您的视图更加通用和可重用。

您要避免的是让您的视图直接链接到您的模型。控制器的作用是在视图和模型之间进行调解。您应该能够在不接触模型的情况下完全更改视图的实现方式,反之亦然。

于 2013-04-04T01:26:43.253 回答
0

您可以将该方法放在视图界面中的协议中:

@protocol MyViewDelegateProtocol <NSObject>
    -(void)myMethod;
@end
  • 您在视图中放置了一个名为 delegate 的 NSObject 类型的新属性。
  • 您使您的视图控制器遵守该协议,并在它启动视图时将委托属性分配给 self。
  • 您在视图控制器实现中实现 myMethod 。
  • 现在您只需在需要时从您的视图中调用 [delegate myMethod] 即可。
于 2013-04-04T01:27:07.650 回答