On Feb 22, 2008, at 20:39, Jack Repenning wrote:
I have some code inherited from someone else (so I have no answers
to why it's the way it presently is) that's handling retention in a
way I find confusing, and think is not in accordance with the
spirit of the law. But I can't quite figure out how to do it
"right". Is there a pattern I should be following, and at what
point am I diverging from it?
The quandary involves two classes, call them "Controller" and
"UI". Controller is created when the NIB is loaded, and lives
effectively forever. From time to time, Controller needs to create
an instance of UI, to manage some user interaction (take some
parameters, do some work, show status, you know the drill). It's
possible for there to be several UI objects alive and on-screen at
once. My problem concerns the retention of the UI objects.
In the current structure, Controller performs
{
UI *ui = [[UI alloc] initWithContext: context];
[ui run: @selector(doSomething) title: @"Title"];
}
That is: the UI object is alloc'ed (creating a release obligation),
but is not (auto)released here, nor is any reference to it saved
anywhere so it may be (auto)released later. Controller has nothing
to do with releasing this object, which is the bit that sticks in
my craw.
Rather, over in UI we have:
-(void)windowWillClose:(NSNotification *)aNotification
{
[self autorelease];
}
That is: after UI has done all it needs to do, and the user clicks
the final button (connected here), it autoreleases itself,
completes, and the pool finishes it off.
This is all working; nothing leaks, nothing is prematurely
dealloc'ed. But having the alloc and (auto)release in separate
classes seems unsound.
It works but ugly. This is not the way memory is managed usually,
which will cause any new developer to waste time on this code.
I found an earlier thread in this list,
http://lists.apple.com/archives/cocoa-dev/2002/Jul/msg01001.html
which is darned close to my situation (almost, but not quite,
totally like). This thread solves its very similar problem by
having Controller keep a ref to UI, and release it during
Controller's dealloc. I can't quite see how to handle that in my
case. A minor problem is that I may have an unpredictable number
of these UI objects about, so I'd need an NSMutableArray of them or
something, not just a scalar field. But a bigger problem is that
Controller isn't dealloc'ed until the end of the program, which is
far too late: it's a long-lived, server-like program, I'd be
accumulating these UI objects forever.
You may want to keep the active UI object in a collection and remote
them when they are done.
- Is my eternal, shared Controller bogus, and I should be finding
some way to create multiple Controllers, and destroy them more often?
There is nothing bogus in controlling multiple objects. If the
controller is simple and easy to maintain and change, it is probably
fine.
- Is there some way to get the windowWillClose event passed back
to Controller, rather than to UI, so the autorelease can happen there?
The simplest solution would be to add a delegate to the UI. The
controller will set itself as the delegate when creating a UI object,
and the UI will notify the delegate when its done.
If there are other objects that may be interested in the UI
completion event, you may like to use notifications instead. The
controller will observer UI notifications and the UI will post
notification when its done.
Best Regards,
Nir Soffer
_______________________________________________
Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
Please 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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]