OK, so I understand delegates. I am perplexed (in a language design sense) that in some recent Swift work I have encountered delegates that can only be implemented with an "override" qualifier. Specifically "controlTextDidEndEditing" as NSTextFieldDelegate of a NSTextField UI element. (Yes, this is OS X dev work, not IOS).
When implementing this delegate Xcode insists on an override qualifier for the func. If it is a "delegate" function, then what code/functionality up the hierarchy am I overriding and should I care? Inserting super.controlTextDidEndEditing in the implementation simply led to an infinite loop. My comprehension (perhaps faulty/incomplete) of a delegate has been that it defines a signature that the implementation matches.
The context is test panel with an TextField and Label dropped into a ViewController, a trivial test exercise. The only scenario that I can arrive at is that somewhere in the hierarchy above the ViewController some other class is already implementing controlTextDidEndEditing, which leads to the override requirement as soon as I try to implement it, which implies that I am destroying some existing level of functionality. I did experiment with subclassing NSTextField with the same "override" required result.
Can anyone further my education by explaining the ins and outs of this ?
Thanks,
Alan.
This is an example of an obsolete design pattern in older Objective-C code that doesn't map well to Swift. (It's more of a problem with the earliest AppKit code rather than UIKit. Expect Apple to continue to clean up these issues as time goes on.)
controlTextDidEndEditing isn't actually part of the NSTextFieldDelegate protocol (or any other protocols). Instead, it's declared as an Objective-C "informal protocol":
@interface NSObject(NSControlSubclassNotifications)
- (void)controlTextDidBeginEditing:(NSNotification *)obj;
- (void)controlTextDidEndEditing:(NSNotification *)obj;
- (void)controlTextDidChange:(NSNotification *)obj;
@end
An informal protocol is like a class extension without an implementation, and their use dates back to a time when Objective-C didn't support formal protocols or optional protocol methods.
Swift doesn't have informal protocols. Instead, it appears as an extension to NSObject.
extension NSObject {
func controlTextDidBeginEditing(obj: NSNotification)
func controlTextDidEndEditing(obj: NSNotification)
func controlTextDidChange(obj: NSNotification)
}
But Swift doesn't know that this is an informal protocol. As a result, Swift will let you call controlTextDidEndEditing() on any NSObject, even though NSObject does not implement that method.
Likewise, when you implement one of these methods in your own class, Swift will force you to use the override keyword because it thinks you're overriding a method on NSObject, even though that's not the case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With