How to instantiate subclass of NSDocumentController?

Hello,

I want to subclass NSDocumentController, but I could not find the information in Apple document how to subclass.

According to ChatGPT, it can be instantiated by [MyDocumentController sharedDocumentController]; before NSApplicationMain() as the following code. It seems working well in my test environment.

int main(int argc, const char * argv[]) {
    [MyDocumentController sharedDocumentController];
    NSApplicationMain(argc, argv);
}

But, I am not sure whether it is officially correct to instantiate so early (before calling NSApplicationMain). Is there any official information what is correct way to instantiate subclass of NSDocumentController?

Answered by DTS Engineer in 803207022

Is there any official information what is correct way to instantiate subclass of NSDocumentController?

You can find our official guidance on this in "You Rarely Need to Subclass NSDocumentController", which says:

  • You can make an instance of your subclass in your app’s main nib file. This instance becomes the shared instance.

  • You can create an instance of your subclass in your app delegate’s applicationWillFinishLaunching: method.

However, what's actually going on here is what's described in NSDocumentController.init():

"The first instance of NSDocumentController or any of its subclasses that is created becomes the shared instance."

In other words, you're basically in a "race" with the broader system, so a long as you call "init" first, your NSDocumentController will "win". Whether or not that matters... depends on what you're app actually does. In a "basic" app configuration, moving that code into main does nothing and applicationWillFinishLaunching would work just as well. The "nib/xib" based approach is mentioned in cases where the app is initializing it's document(s) in it's nib/xib, so it needs to have it's document controller in place "first".

Doing something like this:

According to ChatGPT, it can be instantiated by [MyDocumentController sharedDocumentController]; before NSApplicationMain() as the following code.

Is basically just a slightly odd variant of the nib/xib loading approach.

In our modern world, the one case this doesn't catch is libraries that are executing code at "load" time, which ends up executing before main() even runs. In theory, I think you could handle that case by calling having MyDocumentController implement a "load" class method.

In terms of what you "should" do, as a grumpy old man™, I'd personally use either of the two approaches above and then fix/remove any frameworks that were forcing execution before main. If running code before NSApplicationMain bothers you, needing "load" is MUCH worse.

However, in practice, the system seems to be FAR more tolerant of code executing before main() than I'd consider "reasonable". I've seen apps that have basically done "all" of their primary initialization, including starting a complex network stack and initializing complex view object like WKWebView... BEFORE main() actually ran. Architecturally, most of AppKit (and UIKit) works by "attaching" on to the main threads runloop, which is then run by NSApplicationMain(). The individual components are relatively self contained, so a long as everything is "in place" before the runloop starts running, the order doesn't ACTUALLY matter that much*.

*Until it does and something weird happens.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

Is there any official information what is correct way to instantiate subclass of NSDocumentController?

You can find our official guidance on this in "You Rarely Need to Subclass NSDocumentController", which says:

  • You can make an instance of your subclass in your app’s main nib file. This instance becomes the shared instance.

  • You can create an instance of your subclass in your app delegate’s applicationWillFinishLaunching: method.

However, what's actually going on here is what's described in NSDocumentController.init():

"The first instance of NSDocumentController or any of its subclasses that is created becomes the shared instance."

In other words, you're basically in a "race" with the broader system, so a long as you call "init" first, your NSDocumentController will "win". Whether or not that matters... depends on what you're app actually does. In a "basic" app configuration, moving that code into main does nothing and applicationWillFinishLaunching would work just as well. The "nib/xib" based approach is mentioned in cases where the app is initializing it's document(s) in it's nib/xib, so it needs to have it's document controller in place "first".

Doing something like this:

According to ChatGPT, it can be instantiated by [MyDocumentController sharedDocumentController]; before NSApplicationMain() as the following code.

Is basically just a slightly odd variant of the nib/xib loading approach.

In our modern world, the one case this doesn't catch is libraries that are executing code at "load" time, which ends up executing before main() even runs. In theory, I think you could handle that case by calling having MyDocumentController implement a "load" class method.

In terms of what you "should" do, as a grumpy old man™, I'd personally use either of the two approaches above and then fix/remove any frameworks that were forcing execution before main. If running code before NSApplicationMain bothers you, needing "load" is MUCH worse.

However, in practice, the system seems to be FAR more tolerant of code executing before main() than I'd consider "reasonable". I've seen apps that have basically done "all" of their primary initialization, including starting a complex network stack and initializing complex view object like WKWebView... BEFORE main() actually ran. Architecturally, most of AppKit (and UIKit) works by "attaching" on to the main threads runloop, which is then run by NSApplicationMain(). The individual components are relatively self contained, so a long as everything is "in place" before the runloop starts running, the order doesn't ACTUALLY matter that much*.

*Until it does and something weird happens.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

How to instantiate subclass of NSDocumentController?
 
 
Q