Pregunta

I have a NSWindow/Controller that I display modal. It has a "Close" button hooked up to an action like this:

- (IBAction)close:(id)sender
{
    [self.window orderOut:sender];
    [self.window close];

    [[NSApplication sharedApplication] stopModal];
}

From my main window, I display the modal:

- (IBAction)modal:(id)sender
{
    NSLog(@"Before: %lu", [[[NSApplication sharedApplication] windows] count]);

    ModalWindowController *modal = [[ModalWindowController alloc] initWithWindowNibName:@"ModalWindowController"];
    [[NSApplication sharedApplication] runModalForWindow:modal.window];

    NSLog(@"After: %lu", [[[NSApplication sharedApplication] windows] count]);
}

I open and close the modal a few times, and the output is like this:

2013-01-17 14:36:08.071 Modals[3666:303] Before: 1
2013-01-17 14:36:08.962 Modals[3666:303] After: 2
2013-01-17 14:36:09.578 Modals[3666:303] Before: 2
2013-01-17 14:36:11.009 Modals[3666:303] After: 3
2013-01-17 14:36:12.108 Modals[3666:303] Before: 3
2013-01-17 14:36:12.910 Modals[3666:303] After: 4

So, [[[NSApplication sharedApplication] windows] count] only ever increases.

I would expect it to increase and decrease as I open and close the modal window. My application uses ARC. Can someone explain this to me?

Thank you in advance

¿Fue útil?

Solución

You're closing your window, but that's not deallocating it because your window controller ModalWindowController is still retaining it. I don't see anything in your sample to indicate the window controller is being released.

The simplest answer to give you is to have you release your window controller following your call to -runModalForWindow:.

What you may be expecting is the window controller to close when your window does. That's something you have to make happen yourself. From "Window Closing Behavior," in Apple's documentation:

If you want the closing of a window to make both window and window controller go away when it isn’t part of a document, your subclass of NSWindowController can observe NSWindowWillCloseNotification or, as the window delegate, implement the windowWillClose: method and include the following line of code in your implementation: "[self autorelease];"

In your scenario, this might not be the best approach, because you'd wind up disposing of both your window controller and window before you get a chance to call -stopModal.

Otros consejos

Give a look to this NSWindow method:

- (void)setReleasedWhenClosed:(BOOL)releasedWhenClosed;

If you set it to YES your window will be released when closed. But be careful that when the count is to zero it will be deallocated.

For the Swift 5 people, this works for me. In this case I want to close every window properly, unless it's the last one, in which case I want it to hide

  func windowShouldClose(_ sender: NSWindow) -> Bool {
    sender.isReleasedWhenClosed = true
    if NSApp.windows.count > 1 {
        return true
    }
    NSApp.hide(nil)
    return false
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top