Re: Completely remove a window (from NSApp)?
Re: Completely remove a window (from NSApp)?
- Subject: Re: Completely remove a window (from NSApp)?
- From: Jerry Krinock <email@hidden>
- Date: Sun, 31 Dec 2006 07:45:56 -0800
- Thread-topic: Completely remove a window (from NSApp)?
on 06/12/27 18:59, PGM at email@hidden wrote:
> I made a little test-project and it seems that the magic is not so
> much in -setReleasedWhenClosed itself, but simply in releasing the
> instance of NSWindow...
>
> If I recall correctly, for document windows normally
> NSWindowController takes care of releasing the window it manages, so
> that when a NSDocument instance releases its windowControllers, the
> windowControllers release their windows. So you probably hacked your
> NSDocument subclass in such a way that this does not happen anymore.
Yes, it took me a few days to get this figured out, but the actual story is
more complicated than we thought...
-setReleasedWhenClosed is not the answer, because, in the documentation for
-[NSWindow setReleasedWhenClosed:], it is plainly stated:
"Release when closed, however, is ignored for windows owned by window
controllers."
Well, I have a window, owned by an NSWindowController subclass, which I
would like to be released when closed. What do I do?
The answer seems to be that the owning NSWindowController WILL ALWAYS
-release the window, and also (magically) it will be removed from NSApp's
-windows, when the owning NSWindowController itself is dealloced. And this
is, it would seem, the natural death that the Cocoa gods have intended for
"NSWindowControlled" windows.
The reason my windows weren't going away is because, of course, code that I
wrote many months ago, when I was a newer newbie, was full of stupid memory
leaks and retain cycles, so that my NSWindowController was not getting
deallocced, therefore its window was not getting deallocced.
But there's a little more. After I fixed all the memory leaks and retain
cycles, I found that my app would crash after the window disappeared. The
reason for the crashes was the -setReleasedWhenClosed workaround method that
I had implemented a few days ago, the one that is supposedly "ignored".
Hmmm...
Again, my workaround method was:
- (void)removeWindow {
[[self window] setReleasedWhenClosed:YES] ;
[self close] ;
}
and it was invoked just before the final -release was sent to the
NSWindowController, which now also sends the final -release to the NSWindow.
But it's not quite being "ignored" as documented. By asking
BOOL isSet = [self window] isReleasedWhenClosed] ;
I get YES immediately after I set it, but apparently some kludge in Cocoa
clobbers it to NO soon afterward, and this is how it is "ignored". My
workaround outsmarted their kludge by setting it immediately before it was
needed, so their kludge did not get a chance to clobber it. So, my
workaround did indeed close, release and deallocc the window.
Then, a few microsecs later, the NSWindowController itself is deallocced,
and, apparently, sends its regular -release to its now-deallocced NSWindow,
and you know the rest of the story.
So, the solution to the original question is: If you want an
"NSWindowControlled" window to be deallocced and removed from NSApp's
-windows, practice proper memory management, and both these outcomes will
occur when its NSWindowController is deallocced. Do not use the workaround
-removeWindow method which I posted earlier in this thread.
I still think it would be nice if, instead of automagically removing them,
NSApp exposed a -removeWindow method, for those of us who want to rely on
its -windows, without having to do perfect memory management. But my memory
management is perfect now :|
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden