我了解协议的用途(使类型符合一组方法或/和属性的列表),但我不了解具有所有可选方法的协议的目的是什么。一个例子是UITextFieldDelegate
。
如果协议中的所有方法都是可选的,为什么要遵守协议而不是在类中从头开始编写方法?在这种情况下,我看不出遵守协议的好处或目的是什么。
那里的可选方法是否只是可以实现的功能建议?
我了解协议的用途(使类型符合一组方法或/和属性的列表),但我不了解具有所有可选方法的协议的目的是什么。一个例子是UITextFieldDelegate
。
如果协议中的所有方法都是可选的,为什么要遵守协议而不是在类中从头开始编写方法?在这种情况下,我看不出遵守协议的好处或目的是什么。
那里的可选方法是否只是可以实现的功能建议?
默认情况下,协议中的所有方法都是必需的。如果一切正常运行都不需要,则每种方法都必须标记为可选。
如果协议中的所有方法都是可选的,为什么要遵守协议而不是在类中从头开始编写函数?
遵守协议允许您的类告诉另一个对象它拥有的方法,而另一个对象不需要知道您的类。这在使用委托时非常有用,因为它允许委托决定他们希望接收/提供给另一个类的信息。
例如,UIScrollViewDelegate
协议只定义了可选方法。假设我们有一个类Foo
,当事情发生变化时,我们想知道UIScrollView
.
如果我们决定放弃该协议并从头开始实现这些功能,我们如何知道UIScrollView
我们实现了哪些方法以及在某些事件发生时调用哪些方法?没有什么好办法可以查出来。什么时候UIScrollView
构建的,它不知道,Foo
所以它不知道它实现了什么方法。此外,Foo
无法知道UIScrollView
.
但是,当UIScrollView
它建成时,它确实知道UIScrollViewDelegate
. 因此,如果Foo
符合UIScrollViewDelegate
协议,现在有一个共同的定义,两者都Foo
可以UIScrollView
遵循。所以Foo
可以实现它关心scrollViewDidScroll:
的任何方法,比如UIScrollView
只需要检查委托是否实现了UIScrollViewDelegate
.
从历史上看,对于 Cocoa 中的代表和数据源,使用了非正式协议。非正式协议是通过类的类别实现的NSObject
:
@interface NSObject (NSTableViewDelegate)
- (int)numberOfRowsInTableView:(NSTableView *)tableView;
// ...
@end
后来,引入了协议中的可选方法。此更改导致更好地记录类责任。如果您在代码中看到该类符合NSTableViewDelegate
,则您怀疑某处存在由此类的实例管理的表视图。
此外,此更改会导致在编译时进行更严格的检查。如果程序员不小心分配了错误的对象delegate
或dataSource
属性,编译器会发出警告。
但你的假设也是正确的。可选方法也是对可能功能的建议。
该协议为一个对象和另一个对象之间的接口建立了契约。方法是可选的这一事实只是表明您不必实现该特定方法,但如果您的应用程序需要它,您可以。
通常,如果您遵守所有方法都是可选的协议,那么您这样做是有原因的,即您计划实现这些方法中的一个或多个。仅仅因为协议的所有方法都是可选的,并不意味着您不会实现它们中的任何一个,而只是您可以选择与您的特定情况相关的方法。
例如,考虑UITextFieldDelegate
协议。您通常会遵守这一点,因为您想指定,例如,是否应允许将某些字符插入到文本字段中,或者按下回车键时要执行的操作。有时您只想实现前者。有时您只想实现后者。有时你两者都做。但仅仅因为您选择实施其中一项并不意味着您一定要执行其他一项(但如果您愿意,您可以这样做)。不过,坦率地说,如果您真的不想实现任何方法,您可能甚至不会费心指定delegate
文本字段的类型,也不会费心指定您遵守协议。
底线,仅由可选方法组成的协议基本上说“如果你需要它,这是你可以选择实现的方法的文档化接口”。该协议对于建立可能的接口仍然非常有用,但不会强迫您实现那些您不需要的方法。