封装 iOS 逻辑

Encapsulating iOS logic

我正在创建一个 UITextField 来格式化数字。我最初的想法是我将 subclass UITextField 并将格式化数字的逻辑添加到此 subclass。我的想法是,这个逻辑和我的mainViewController没有关系,应该封装到控件本身。

所以现在我有一个子class。我现在需要做的就是监听一个事件,例如 - (BOOL)textField: shouldChangeCharactersInRange: replacementString:.

然而,将委托设置为 self 似乎不是一个好的设计实践,我不得不说我有点惊讶。将控制逻辑封装在 subclass 而不是视图控制器或完全独立的 class.

中对我来说是完全有意义的

我目前的方法是向 UITextField 添加一个目标操作,它会侦听任何更改 - 但这感觉不对。我想使用委托,但它似乎不受欢迎。

因此,如果委托方法只是为了传递给其他对象,对象应该如何封装与这些事件相关的逻辑,而不使用通知或 KVO 或类似的东西?

为什么应该将事件的处理交给 ViewController 而实际上应该由控件来处理该逻辑?

在 iOS/OS X 中,给 UI 元素很多自己的逻辑是不常见的,因为这违反了 Cocoa 的 Model-View-Presenter 设计(Apple 称之为 Model -View-Controller,但 Cocoa MVC 不像 classic MVC,而是像 MVP)。在 MVP 中,视图尽可能地转储。他们唯一的任务就是展示他们被告知要展示的东西。这就是为什么他们被称为"Presenters",他们只会呈现一些东西。

而在 Cocoa 中,通过 subclass 扩展功能并不常见。 Cocoa 是围绕组合和委托设计的。所以你用简单的组件构建复杂的组件(这称为组合)并有一个委托来定制功能,所以通常不需要子class你的class。

UI 元素的逻辑通常在控制器对象中。 Model是数据,controller是逻辑,presenter/view就是UI.

如果您想将所有这些封装在一个 class 中,请不要使用 subclassing,请使用组合。 Subclass UIView 创建自定义视图并在该视图中使用普通 UITextField:以编程方式创建它,将其保存在实例变量(或私有 属性)中,将它作为子视图添加到自己([self addSubview:...]),然后将自己设置为它的委托来处理事件。

当然subclassing UIView也是subclassing,但是subclassing UIView是创建自定义的唯一方法视图(否则 UIView 必须是一个协议)并且它非常简单,因为您几乎不需要覆盖任何东西,并且您需要(或可能想要)覆盖的内容已得到很好的记录。

考虑 UIView 实际上是为 subclassing 设计的(文档中有很多关于 subclassing 的注释),UITextField 不是(这个词subclassing 甚至不存在于其文档中)。 Objective-C 没有 final 关键字来防止 subclassing,所以按照惯例,考虑所有 classes final 除非有 subclassing 注释(如果有是这样的关键字,UITextField 最喜欢是 final).