Deallocate WindowController + ?

(macOS) In my AppDelegate I have "menu > new window" as an array of WindowControllers (+ ViewController / View with WKWebView), if I close the window and remove the WC from the array I don't think everything is deallocated from the memory. Not sure what the right practive is to make sure it's all removed (inc. WKWebView).


Any suggestions ?

Replies

Removing from the array is not enough: you just get it out of the array, but the object still exists.


Before removing from the array, you should set the controller to nil and implement a deinit in the controller.

Thanks, but it's coming up with ("func deinit() {}") "cannot be used".


So if I get it ... let thisWindowController = windowControllers[i]

Then thisWindowController = nil

Then remove from array.


There is one other thing. With the main menu in my storyboard I don't have "Close Window" but appears when the App is running. How can I handle this to use for unloading the WindowController ?

let will not work.


You should do :

windowControllers[i] = nil

Then remove from array


For the Close Window:

- look at the appController connections in IB

- you should see a CloseDocMenuItem

- I guess you could override its IBAction

>> windowControllers[i] = nil


This doesn't achieve anything. Just removing that entry from the array also eliminates the retaining reference to the window controller. There's no need to set it to nil first, and (since the array elements are likely to be non-optional types) you won't actually be able to do it anyway.


The problem is that there is retain cycle somewhere else that's keeping the window controller alive. For example, the window controller might have a strong reference to the view controller, and the view controller might have a strong reference to the window controller. Breaking that reference cycle by setting one of the references to nil is usually what's required.

The WindowController & ViewController are connected in a storyboard, I guess the storyboard's relationship between the two is strong. I'f I eliminate the WindowController this wouldn't eliminate the ViewController ?


As a noob I should get this straight. Using ...

var this: type!

Is a strong reference, and

var this: type?

is not ?

It's not a problem if the storyboard has strong references to the controllers, but it is a problem if the controllers have mutual references. (It would be a problem if they had references to the storyboard, but that is not the case, unless you've added such references yourself.)


What I would suggest is that you (temporarily) change your window controller subclass to be private ("private class MyWindowController: NSWindowController …"), and see where errors show up in the rest of your code indicating that the window controller is referenced. If there are not a lot of them, you can check each of those sites (well, instance and global variables, since local variables don't cause retain cycles) and look for one that's causing the problem.


Both of your declarations are strong references. Optionality doesn't affect the kind of reference. A non-strong refefence would look like one of these:


     weak var this: type? // weak references must be optional, or ...
     unowned var this: type! // typically some kind of optional, since you typically can't set the initial non-nil value at compile time

Thanks, I learned something.


So I tested in my code :

windowControllers is an array of MyController

windowControllers[i] = nil

And surprisingly, that does not call deinit for MyController. I thought it would.

So I tried removing from the array: it does not call deinit either.

Did you find a solution ?

No, did not solve yet.


May be it's because

windowControllers is an array (of MyController?) that is declared as a global var.

So I cannot declare it weak.

My account safety yes or no help me talk

Found a solution.


In other classes I had strong references to MyController. I declared them as weak, and it's all fine now.