【问题标题】:MVC Model - Should controller access view's controls directly?MVC 模型 - 控制器应该直接访问视图的控件吗?
【发布时间】:2013-03-16 16:20:39
【问题描述】:

我正在学习 iOS 开发的东西,我在教程和书籍中发现控制器层通常可以直接访问视图的控件(文本字段、标签等)。让我们考虑这样一个例子:

假设 View 有一个名为 lblResult 的标签和一个名为 txtDataToAnalyze 的文本字段。比在控制器界面中我们有这样的东西:

@property (nonatomic, retain) IBOutlet UILabel* lblResult;
@property (nonatomic, retain) IBOutlet UITextField* txtDataToAnalyze;

以及实现文件中的一些@synthesize 语句。

我有一些 JavaSwing 开发经验,其中大多数人认为我是在没有任何 GUI 构建器的情况下手动编写的,而我通常在 MVC 中做的是通过 getter/setter 访问 View 的控件。例如:void setResult(String resString);String getDataToAnalyze();。这样,控制器只知道视图中显示了什么条信息,而不知道如何显示它们。我觉得比较灵活(以后改视图层比较容易)。

我知道 iOS 有一些特定的规则,引入了 XIB/NIB 文件等,所以也许我的怀疑在 iPhone/iPad 开发的情况下完全没有用。但是我打算为 iOS 写一些更严肃的应用程序(实际上是从 Java Swing 中“重写”它),这就是我想问你的原因:

你认为,我应该改变我的思维方式并习惯新的(对我而言)方法(xib 文件,使用拖放创建 GUI 和 为控制器提供有关数据应如何在视图中显示的信息) ??你在入手 iOS 时有过类似的疑惑吗?

【问题讨论】:

  • 根据我的经验,更典型的做法是有一个UIViewController 子类,它直接设置标签的文本、获取文本字段的文本值等等。我有点想知道这个问题是否不会在programmers SE 上得到更好的回应。

标签: ios objective-c model-view-controller design-patterns


【解决方案1】:

简答:

是的,我认为您绝对应该花一点时间来习惯使用 Interface Builder (IB) 来制作 NIB 和故事板,并让 IB 为您创建 IBOutletIBAction 引用,用于您使用的那些控件需要互动。一旦您精通它,您就会对生成易于维护的代码的生产力印象深刻。不要太快解雇 IB。

就让控制器直接与IBOutletIBAction 引用交互而言,这是简单用户界面的常见做法。如果您有一些真实世界的示例,请发布一个带有屏幕快照的新问题,我们可以提供更实用的指导。

长答案:

  1. 您的部分问题似乎是由于担心看到正在与视图控件进行详细交互的视图控制器。问题是,如果您想将控制器与视图的一些实现细节隔离开来,那么继续对视图进行子类化并将视图特定的东西放在那里。 IB 可以与视图控制器子类以及视图子类进行交互。因此,您可以愉快地使用 IB 并且仍然将您的视图控制器与其中一些实现细节隔离开来。

    就个人而言,我只在视图达到某种主观复杂度阈值时才对UIView 进行子类化(例如,对我而言,该阈值是当我发现自己在做一些复杂的动画时,例如使用CADisplayLink;复杂的手势识别器,等等。)。我还将那些属于它们自己的逻辑实体的子视图子类化(例如UITableViewCellUICollectionViewCell)。但是对于我与模型交互以设置控件属性、与文本字段交互等的简单视图,我认为将其放在视图控制器中很好。话虽如此,如果我的控制器中有很多特定于视图的代码与我的模型与视图的集成无关,那么开始子类化UIView 并将仅视图代码转移到其中。

  2. 您的问题中隐含的是以编程方式构建视图而不是使用 NIB/故事板的概念。在我看来,使用 Interface Builder (IB) 来构建你的 UI 更容易开发和维护。做一个以编程方式构建视图的测试项目可能有一些教学价值,所以你真的了解发生了什么,但在那之后,我想你会发现自己很快就会被故事板所吸引。当您开始做超出标准 IB 控件功能(例如复杂的自定义容器视图等)的事情时,您将有很多机会编写自己的非 IB 代码。肯定有人更喜欢以编程方式开发视图,但我认为您无法超越 IB 生成的 UI 的开发速度和易于维护。

【讨论】:

    【解决方案2】:

    一般来说,控制器不知道视图,但视图知道控制器。

    四人帮说:

    “MVC 还允许您更改视图响应用户输入的方式,而无需更改其视觉呈现。例如,您可能希望更改它响应键盘的方式,或者让它使用弹出菜单而不是命令键。MVC 将响应机制封装在 Controller 对象中。控制器有一个类层次结构,可以轻松创建新控制器作为现有控制器的变体。

    视图使用 Controller 子类的实例来实现特定的响应策略;要实现不同的策略,只需用不同类型的控制器替换实例即可。甚至可以在运行时更改视图的控制器,让视图改变它响应用户输入的方式。例如,可以禁用视图,使其不接受输入,只需给它一个忽略输入事件的控制器。

    视图-控制器关系是策略 (315) 设计模式的一个示例。策略是表示算法的对象。当您想要静态或动态地替换算法时,当您有很多算法变体时,或者当算法具有要封装的复杂数据结构时,它非常有用。”

    【讨论】:

    • 一个视图通常只显示控制器从模型推送给它的内容,那么它为什么要知道控制器呢?
    • @CarlVeazey 为了通知控制器一些 UI 操作。接下来,控制器可以通过某种特定方式修改模型的状态...
    • @guitar_freak 我还没有看到在 iOS 上付诸实践。大多数 UI 控件使用target/action pattern,这是一种策略模式,但控件对其目标仍然非常不可知,而通常视图控制器对控件的用途了解更多。
    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 2012-08-23
    • 2011-06-26
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多