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: Tue, 8 Jun 2004 19:49:49 -0700
On Jun 8, 2004, at 2:46 AM, Allan Odgaard wrote:
On 8. Jun 2004, at 11:06, Dennis C. De Mars wrote:
So, even in this simplest of examples the NSWindowController object
is caught in a deadly embrace with the view object binding to it,
which the NSDocument seems to be able to break.
The problem I had did involve NSDocument, but I do think that a window
controller is more susceptible to the retain-cycle problem.
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?
Based on my experiments with bindings in very simple examples with an
NSDocument class and an NSWindowController class as File's Owner
respectively, I came up with a paradigm for using bindings while
avoiding the retain cycle.
My first observation was that the document as File's Owner was working
properly with bindings to the document model objects. My assumption is
that this works because the bindings retain the document, the document
retains the window controller and the window controller retains the
window (which retains the view objects with the bindings) and that the
NSDocument has the ability to release the window controller and window
when it knows it is closing. This happens when it receives the close
message, it doesn't have to happen in the dealloc method, which is why
it can break the retain cycle.
Actually, in the case where the window controller is File's Owner, the
window controller could also do this in theory, but it apparently
doesn't -- it maintains a retain on the window even after it knows the
window is supposed to close, relying on its dealloc to do the final
release, which never happens because the bindings have retains on the
window controller. 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 --
clearly NSWindowController was written with the assumption that the
window and subviews of the window would not retain the controller,
which is no longer the case when bindings are used. If
NSWindowController could be redesigned to completely release all of its
retains on the window (even if only on user request) all of the
following would be unnecessary.
So my first thought was that I would create some "model object" or
proxy for the model objects that would be the File's Owner. The window
controller would then be created programatically. It seemed to me the
window controller would not be of much use if it could not be File's
Owner, but then I realize that it could still be set manually to be the
window's delegate, so it would still have some functionality. Not being
able to connect window controller outlets in the nib file would still
be a significant disadvantage.
Then I had two more thoughts that make the scheme more workable:
1) The model object proxy would be not much more than a conduit to my
document object if I keep all the model objects there, so why not just
make the document object the File's Owner? The difference from the
conventional arrangement would be that the document would not be
allowed to create its own internal window controller (so we can still
have our own custom window controller).
2) The window controller object, then, can be instantiated as a top
level object in the same nib file. No binding will be made to window
controller object, but since it is in the nib file it can connect
outlets to view object and be the target of actions from view objects.
So this is what I did. I set the nib file up as above. I instantiate
the nib file in the document class' -makeWindowControllers method. In
-makeWindowControllers, the nib file is instantiated using NSNib.
The document class needs two outlets for the window controller and the
window, which are both top level objects. The document object is
responsible for releasing these objects, since the nib file was
instantiated via NSNib. Using the window controller outlet, the
documemt adds the window controller using -addWindowController. The
window controller can then be released since the document is retaining
it in its window controller list.
You have to make sure the top level objects (the window, and, if you
didn't already release it, the window controller) are released in the
close method of the document. This is enough to break the retain cycle.
That's about it, except for making all the right connections in IB. I
tried this on a simple example and it seems to work. I haven't
exercised it with a complex example so I don't know if there are any
gotchas due to the fact that it deviates somewhat from the standard
paradigms for using nib files with documents and window controllers.
Anyway, the best thing would be for Apple to fix the binding retain
situation so I would have to go through all this!
- 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.