1
votes

I'm creating a new NSWindow:

- (void)newWindow
{
    if (!_myWindow)
    {
        self.myWindow = [[myWindowController alloc] initWithWindowNibName:@"myWindow"];

    }

    [self.categoriasView showWindow:self];
}

But I want to release the window object when the window is close from the NSWindowController using :

- (void)windowWillClose:(NSNotification *)notification
{

}

I have tried [self.window setReleasedWhenClosed: YES]; but the object still there after the window is close.

Any of you knows how can release the NSWindow object after the window is close?

I really appreciate your help

2

2 Answers

16
votes

First, there's a difference between the window (instance of NSWindow or a subclass) and the window controller (instance of NSWindowController or subclass). Your question and the code seems to use both terms interchangeably.

When you're using a window controller, you do not release the window itself. The window controller owns it and it will release it when it's done with it. Likewise, releasedWhenClosed is ignored for windows owned by window controllers. This is documented with the getter -isReleasedWhenClosed.

Your code apparently keeps a strong reference to the window controller in the myWindow property (although your code snippet also refers to a categoriasView property in a manner that seems like it's a window controller). If you clear that property, you will release the window controller. If that's the last strong reference, then the window controller will be deallocated and it will release the window.

You can clear the property in the -windowWillClose: method of the window delegate, if you have assigned a delegate for the window. Often, but not necessarily, the window controller is the window's delegate. You can set that up in the NIB. However, in that case, it's not very convenient for the window controller to clear the property of its owner.

Another approach is to have the owner of the window controller observe the NSWindowWillCloseNotification emitted by the window. You can set this up like so:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:self.myWindow.window];

Then, you can implement a -windowWillClose: method in an object other than the window's delegate. In that method, you would do:

- (void)windowWillClose:(NSNotification *)notification
{
    NSWindow* window = notification.object;
    if (window == self.myWindow.window)
        self.myWindow = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:window];
}
0
votes

my two cents for Catalina.

A bit old post. .. but can be useful:

I attach under shouldClose, (to have a better control.. but it the same.. as a final result)

simply set to nil:

func windowShouldClose(_ sender: NSWindow) -> Bool {

    #if DEBUG
    let closingCtl = sender.contentViewController!
    let closingCtlClass = closingCtl.className
    print("\(closingCtlClass) is closing")
    #endif


    sender.contentViewController = nil // will force deinit.

    return true // allow to close.
}