如果所有方法都是可选的,协议的目的是什么?

What is the purpose of protocols if all methods are optional?

我了解协议的用途(使类型符合一组方法 or/and 属性),但我不了解具有所有可选方法的协议的用途是什么。一个例子是 UITextFieldDelegate.

如果协议中的所有方法都是可选的,为什么要遵守协议而不是在 class 中从头开始编写方法?在这种情况下,我看不出遵守协议的好处或目的是什么。

是否有可选方法作为可以实现的功能建议?

默认情况下,协议中的所有方法都是必需的。如果所有方法都正常运行,则每个方法都必须标记为可选。

If all methods are optional in a protocol, why would you conform to the protocol instead of just writing the functions from scratch in your class?

遵守协议允许您的 class 告诉另一个对象它拥有的方法,而其他对象不需要知道您的 class。这在使用 Delegation 时非常有用,因为它允许代表决定他们希望 receive/provide 给另一个 class 的信息。


例如,UIScrollViewDelegate协议只定义了可选的方法。假设我们有一个 class Foo,我们想知道什么时候事情随着 UIScrollView.

发生变化

如果我们决定放弃该协议并从头开始实现功能,我们将如何告诉 UIScrollView 我们实现哪些方法以及在特定事件发生时调用哪些方法?没有什么好方法可以找到。构建 UIScrollView 时,它不知道 Foo 所以它无法知道它实现了什么方法。此外,Foo 无法知道 UIScrollView.

可以调用哪些方法

然而,当 UIScrollView 被构建时,它确实知道 UIScrollViewDelegate。因此,如果 Foo 符合 UIScrollViewDelegate 协议,那么现在有一个 FooUIScrollView 都可以遵循的通用定义。所以 Foo 可以实现它关心的任何方法,比如 scrollViewDidScroll:UIScrollView 只需要检查委托是否实现了 UIScrollViewDelegate.

中的方法

历史上,对于 Cocoa 中的代表和数据源,使用的是非正式协议。非正式协议是通过 NSObject class:

的类别实现的
@interface NSObject (NSTableViewDelegate)

- (int)numberOfRowsInTableView:(NSTableView *)tableView;

// ...

@end

后来引入了协议中的可选方法。此更改可以更好地记录 class 职责。如果您在代码中看到 class 符合 NSTableViewDelegate,您怀疑某处存在一个 table 视图,该视图由此 class.

的实例管理

此外,此更改会导致编译时进行更严格的检查。如果程序员不小心将错误的对象分配给 delegatedataSource 属性,编译器将发出警告。

但是你的假设也是正确的。可选方法也是对可能功能的建议。

该协议为一个对象与另一个对象之间的接口建立契约。这些方法是可选的这一事实只是说明您不必实现该特定方法,但如果您的应用程序需要它,您可以实现。

一般来说,如果您要遵循一个所有方法都是可选的协议,那么您这样做是有原因的,即您计划实施这些方法中的一个或多个。仅仅因为协议的所有方法都是可选的并不意味着您不会实现其中任何一个,而只是您可以选择与您的特定情况相关的方法。

例如,考虑 UITextFieldDelegate 协议。您通常会遵守这一点,因为您想要指定,例如,是否应允许将某些字符插入文本字段或按下 return 键时要执行的操作。有时您只想实现前者。有时您只想实现后者。有时你会两者兼顾。但是仅仅因为您选择实施一个或另一个并不意味着您一定要执行另一个(但如果您愿意,您可以)。不过,坦率地说,如果您真的不想实现任何方法,您可能甚至懒得指定文本字段的 delegate,也懒得指定您符合协议.

最重要的是,仅由可选方法组成的协议基本上是 "if you need it, this is the documented interface for the methods you may elect to implement"。该协议对于建立可能的接口仍然非常有用,但不会强制您实现那些您不需要的方法。