I would like compiler to detect these errors…

Before all, I have to admint that all the following is my fault, I should be more careful… etc, etc, …


But let me explain.


In an OSX App, I have implemented windowWillClose().

Unfortuately, I forgot (stupid me) to declare thet tha controller conforms to NSWindowDelegate.

Of course, windowWillClose was never called ! But the error remained unoticezd for quite a time (actions in windowWillClose were not critical, more user comfort).


In some cases, compiler is able to detect very complex error patterns. But not this.

Except by using code coverage (or being more attentive when looking at code), is there a way to detect such an error ?


Similar case ; the signature of windowWillClose changed between Swift 2 and 3.

For some reason, I had some calls unchanged in the conversion (unless I mistakenly typed that way in Swift 3)

func windowWillClose(notification: NSNotification) instead of func windowWillClose(_ notification: Notification)

Once again, except by using code coverage, is there a way to detect such an error ?

Replies

According to the Xcode 9.0 release notes (and I think the same statement is still in the 9.1 beta release notes):


"The Swift compiler doesn't produce warnings when a method in a subclass is intended to match an optional method in a protocol adopted by the superclass. For example, if the superclass conforms to UITableViewDelegate, and the subclass declares a method incorrectly named tableView(_:editingStyleForRowAtIndexPath:) instead of tableView(_:editingStyleForRowAt:), the compiler will not warn about it. Additionally, if Swift 3 style inference of @objc is turned off the method will not be called at run time. Make sure to check any such methods carefully. (30489065, SR–3943)"


In your particular example, I would be very surprised if it was the lack of conformance to NSWindowDelegate that caused the problem**. The delegate protocol was formalized in macOS 10.6 (apparently) and it was likely an informal protocol before that. In other words, the "windowWillClose" method likely has always been called if it exists in the delegate class, regardless of actual conformance. (I could be wrong about that, of course, but such a change could break existing apps, so the original behavior is probably set in stone.)


More likely, I guess, is that you didn't explicitly change the method to @objc, as mentioned in the 2nd-to-last sentence of the above quote. If it did match the correct signature, it would be forced to @objc by default. Since it did not match, it defaulted to non-@objc, and so wouldn't be called.




**Well, now that I think about it, adding the NSWindowDelegate conformance will also force the assumed @objc, since it's an @objc protocol.

There’s two parts to this:

  • What Xcode can do for you?

  • What you can do in the absence of better Xcode support?

My recommendation on the first front is that you should file an enhancement request with a specific example of the problem you hit. I don’t know how feasible it would be to catch these things in Xcode, but your bug report will at least put it on the team’s radar (hey hey).

With regards the second point, my general recommendation is that you get into the habit of:

  1. Adding your protocol conformance first

  2. Then using Xcode’s code completion to enter the method name

That’ll ensure that the method always matches the protocol.

This does not, alas, help with the migration issue you mentioned.

ps If you do file any bug reports, please post your bug numbers, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"