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