Changing the delegate of an NSWindow, NSTabView, or NSSplitView managed by a NSWindowController, NSTabViewController, or NSSplitViewController respectively is not supported and will assert.

I see in the release notes of 10.13:


Changing the delegate of an NSWindow, NSTabView, or NSSplitView managed by a NSWindowController, NSTabViewController, or NSSplitViewController respectively is not supported and will assert. When building using Xcode 9 or later, Xcode will now automatically set the delegate outlet on these objects to their owning controllers. If the application was previously changing the delegate of these objects programmatically after view/window loading, the application will now assert.


Ignoring NSSplitViewController, and NSTabViewController because I don't usually use those, what is the justification for not allowing one to set a window's delegate to an object other than its window controller?


Why would a window controller need to be the delegate of its window? If a base NSWindowController relied on the window delegate events, should it not get those privately in some other way (through notifications or private API)? Isn't a large point of delegates, is to allow the app developer to use them? Shouldn't the developer be the one to make this decision? It's pretty typical for the window controller to be the window's delegate, but I don't see why it has to be?

Replies

Extend the protocols without your own functionaly and still use the delegate reference of the protocol with the additional functionality thus you maintain the contract and nothing is broken or just call your version of "delegate" something else ...

I don't know, but I can think of two speculative reasons:


1. There is a longstanding bug in macOS where Cocoa frameworks erroneously confuse delegate objects with controller objects. This could be one way of mitigating the effects.


2. This is in preparation for some upcoming API change, which will be source-breaking for an app that uses a delegate different from the controller. Apple occasionally issues guidance like this, even years in advance.

Thanks for the suggestion, though I'm not really asking if there is another way to accomplish something. I could just subclass NSObject and make my own 'window controller' outlet to the window too and just not use NSWindowController at all.


But I'm interested in finding out, what is the justification for now asserting who the window's delegate is? I didn't think it was Appkit's business who I make the window delegate? Not sure why they care? Only thing I can think of is that the base NSWindowController behavior now relies on window delegate methods, but I wonder why they would make such a weird change?


Does it assert only if the delegate is wired to the window controller in IB? Does the delegate for a window controlled by a window controller have to be the window controller, or do they just not want you to change the window's delegate after it has already been set?