Re: Retain cycle problem with bindings & NSWindowController
Re: Retain cycle problem with bindings & NSWindowController
- Subject: Re: Retain cycle problem with bindings & NSWindowController
- From: "Dennis C. De Mars" <email@hidden>
- Date: Fri, 11 Jun 2004 20:14:40 -0700
On Jun 8, 2004, at 11:36 PM, Dennis C. De Mars wrote:
On Jun 8, 2004, at 8:33 PM, Allan Odgaard wrote:
On 9. Jun 2004, at 4:49, Dennis C. De Mars wrote:
My solution was to send unbind: messages in the
windowWillClose:-notification.
OK, I can see that this would work. Do you have to send an unbind
message to each view object that has a binding?
At least all those which cause retainment of the involved parties.
But in my case I only had a single binding, so not much of a
problem...
[...] If the window controller could be convinced to completely
release the window before it is itself dealloced then the cycle
could be broken but there is no way I know of to do this
You can send setWindow: with nil to the window controller.
Thanks! I missed that possibility. I'm going to try it out, it might
save me from having to go through all that folderol I outlined in my
previous message.
It looks to me like I could override the NSWindowController -close
method and use it there. Well, I'll experiment and see what I can do.
This could be in a response to a 'window will close'-notification.
But there are cases where the window may re-open, and thus one needs
to have the class responsible for releasing the window controller
also perform this workaround.
OK, this is a update to this thread to let everybody know how this
turned out (I wouldn't want anybody looking for info on this problem to
see this and think everything is resolved, because it isn't).
First of all, I'll point out that Allen Odgaard was right about the
"windowWillClose" notification or delegate method being the proper
place to put this "setWindow: with nil". I tried putting it in the
window controller -close method, but there is no guarantee it will be
called.
Also, it does do what is intended: it releases the window controller's
"retain" on the window.
I was so sure this would solve my binding/memory leak problems that I
installed it directly into my real application rather than trying it
first in one of my tiny test applications. The window controller still
hung around after I closed the window, though, so I went back to my
test code to see what was going on.
This test application is minimally modified from the cocoa
document-based project that is generated when you create a new project
in Xcode. This application has one custom window controller class, the
window controller is the File's Owner of a nib file with one window
that contains a single NSTextField control, and the text view has a
binding to a variable that is accessed with a path through the window
controller. When the window is closed, the window controller and window
are not released, even though when I have a similar setup with the
document as the File's Owner, everything _is_ released.
So, I rebuilt the application after adding the following method to the
window controller subclass:
- (void)windowWillClose:(NSNotification *)aNotification
{
[self setWindow:nil];
}
I ran it under ObjectAlloc and determined that the window controller
still doesn't go away when the window is closed. I decided to take a
look at the retain/release call sequence of the NSWindow to determine
why it did not get released, but I couldn'f find it. It _had been
released. The [self setWindow:nil]; statement did what was intended.
Hmmm.
I had already determined from looking at the retain/release sequence
for the window controller that it was almost certainly the retain from
the binding that wasn't being balanced with a release. I went looking
for the NSTextField object that had the binding.
ObjectAlloc said the NSTextField had also been released. But the
NSTextFieldCell object was still there.
At this point the theme music from "Twilight Zone" started playing in
my head. OK, why was this guy hanging around?
Turns out it was retained by the binding also.
It looks like the only way the retain cycle can be broken is, as Allen
suggested in a previous message, to send an unbind message to each view
object that has a binding. The question presents itself, why do things
work (as I outlined in a previous message) when the window controller
object is not the File's Owner, but you get memory leaks when it is the
File's Owner?
My theory at this point is that the window controller is the object
that is responsible for keeping track of the bindings and issuing
unbind commands to the view objects, but it can't do this when it is
itself a target of bindings (perhaps the unbind messages are issued in
the dealloc method).
Or maybe the truth is more complicated than that. It probably is, but
as it is all a black box to me, I think I've gone as far as I can in
trying to work around this problem. I have to get on with development.
I will definitely file a bug with Apple, though -- it's pretty clear
something needs to be fixed.
- Dennis D.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.