使用Swift“为什么”一些委托函数需要覆盖func

时间:2015-04-12 06:42:39

标签: macos swift delegates

好的,所以我理解代表们。我很困惑(在语言设计意义上),在最近的一些Swift工作中,我遇到了只能用“覆盖”限定符实现的委托。特别是“controlTextDidEndEditing”作为NSTextField UI元素的NSTextFieldDelegate。 (是的,这是OS X开发工作,而不是IOS)。

实现此委托时,Xcode坚持使用func的覆盖限定符。如果它是一个“委托”功能,那么我最重要的是层次结构中的代码/功能,我应该关心吗?在实现中插入super.controlTextDidEndEditing只会导致无限循环。我对代理的理解(可能是错误的/不完整的)是它定义了实现匹配的签名。

上下文是测试面板,TextField和Label被放入ViewController,这是一个简单的测试练习。我可以得出的唯一场景是,在ViewController上面的层次结构中的某个地方,其他一些类已经在实现controlTextDidEndEditing,一旦我尝试实现它就会导致覆盖要求,这意味着我正在破坏现有的一些级别功能。我尝试使用相同的“覆盖”所需结果对NSTextField进行子类化。

任何人都可以通过解释这个的细节来进一步教育吗?

谢谢,

艾伦。

2 个答案:

答案 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本身实现为空实现,这就是您需要覆盖的原因。