Storyboard new window ?

In the AppDelegate I've set up a func to open a new window ...


        let mainWindowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "MainWindow") as? MainWindowController
        mainWindowController?.showWindow(nil)


The window appears for a moment then suddenly gone. Can't find how to make a new instance ?

You are (apparently) keeping the only reference to the window controller in a local variable in your AppDelegate method. As soon as execution leaves that scope, there will be no more references, the window controller will be deallocated, and the window closed.


Store the reference in an instance variable instead.

I did try that too but with strange results ...


    var mainWindowController: MainWindowController?


Sometimes it loads a window sometimes it doesn't, I also added a deinit printing if it deallocates and says it has. The most common pattern is that it will work the first time after that goes strange.

The problem isn't in the instance property where you store the reference.


Is this a kind of window that you want to create multiple instances of, over time, or a window that exists only once and is created at application startup? What is the "Presentation" popup setting for the window controller in the storyboard, Single or Multiple?


Please note that lines of code like this:


     mainWindowController?.showWindow(nil)


(line 2 of your original code fragment) are IMO a really bad idea. Your app needs the window controller to have been created — something has gone horribly wrong if not — but this kind of optional chaining does nothing but ignore an error at its source, potentially propagating the situation to some later point in the code where the cause is obscure.You really should check for the error and crash your app immediately if the check fails (the "precondition" library function is intended for this use).

I'm not entirely sure what you mean with the instance variable / property ? I'm mean I know what a variable and it's property is, just not where your going with it. Yeh the presentation is set to multiple.

I meant, the original behavior you asked about was caused by using a local variable, but you solved that by using an instance variable instead. Then you had a different problem, which was nothing to do with the instance variable. I was just emphasizing that this was a different problem, but perhaps I didn't need to.


The next step is to describe the exact behavior when it "goes strange" the second or subsequent times. Am I correct that you're instantiating the storyboard in an action method in AppDelegate, such as when a button is clicked or a menu item chosen?


>> presentation is set to multiple


In that case, unless I'm missing something, a single instance variable isn't going to be enough to hold references to all of the windows you instantiate. You might need an array of window controller references, in which case you'll need code to remove references when the corresponding window is closed, which will involve the window controller "willClose" method, and it starts to make more sense to move all of the management behavior into the window controller [sub-]class.

So the instance variable is ok, good to know. The second problem, as I made the variable optional I thought it could only be referenced as optional. I've made an array for the controllers ...


var windowControllers: [MainWindowController] = []
...
        windowControllers.append(NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "MainWindow") as! MainWindowController)
Storyboard new window ?
 
 
Q