好的,所以我理解代表们。我很困惑(在语言设计意义上),在最近的一些Swift工作中,我遇到了只能用“覆盖”限定符实现的委托。特别是“controlTextDidEndEditing”作为NSTextField UI元素的NSTextFieldDelegate。 (是的,这是OS X开发工作,而不是IOS)。
实现此委托时,Xcode坚持使用func的覆盖限定符。如果它是一个“委托”功能,那么我最重要的是层次结构中的代码/功能,我应该关心吗?在实现中插入super.controlTextDidEndEditing只会导致无限循环。我对代理的理解(可能是错误的/不完整的)是它定义了实现匹配的签名。
上下文是测试面板,TextField和Label被放入ViewController,这是一个简单的测试练习。我可以得出的唯一场景是,在ViewController上面的层次结构中的某个地方,其他一些类已经在实现controlTextDidEndEditing,一旦我尝试实现它就会导致覆盖要求,这意味着我正在破坏现有的一些级别功能。我尝试使用相同的“覆盖”所需结果对NSTextField进行子类化。
任何人都可以通过解释这个的细节来进一步教育吗?
谢谢,
艾伦。
答案 0 :(得分:3)
这是旧的Objective-C代码中过时的设计模式的一个例子,它没有很好地映射到Swift。 (这是最早的AppKit代码而不是UIKit的问题。期待Apple随着时间的推移继续清理这些问题。)
controlTextDidEndEditing实际上并不是NSTextFieldDelegate
协议(或任何其他协议)的一部分。相反,它被声明为Objective-C "informal protocol":
@interface NSObject(NSControlSubclassNotifications)
- (void)controlTextDidBeginEditing:(NSNotification *)obj;
- (void)controlTextDidEndEditing:(NSNotification *)obj;
- (void)controlTextDidChange:(NSNotification *)obj;
@end
非正式协议就像没有实现的类扩展,它们的使用可以追溯到Objective-C不支持正式协议或可选协议方法的时候。
斯威夫特没有非正式协议。相反,它显示为NSObject
的扩展名。
extension NSObject {
func controlTextDidBeginEditing(obj: NSNotification)
func controlTextDidEndEditing(obj: NSNotification)
func controlTextDidChange(obj: NSNotification)
}
但斯威夫特并不知道这是一个非正式的协议。因此,Swift将允许您在任何controlTextDidEndEditing()
上调用NSObject
,即使NSObject没有实现该方法。
同样,当您在自己的类中实现其中一种方法时,Swift会强制您使用override
关键字,因为它认为您正在覆盖NSObject
上的方法,即使事实并非如此。
答案 1 :(得分:0)
您不会覆盖委托,而是覆盖getter和setter。但是,像UITableViewController 这样的类符合委托和数据源,这意味着他们已经实现了这些方法。你重写它们是因为,是的,超类实现了那些。
当你重写委托方法时,除非超类实际执行某些功能,否则我认为你不会进行超类调用。 NSTextField
的{{1}}可能由controlTextDidEndEditing
本身实现为空实现,这就是您需要覆盖的原因。