Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
- Subject: Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
- From: Brian Stern <email@hidden>
- Date: Wed, 19 Nov 2008 10:00:11 -0500
On Nov 19, 2008, at 3:59 AM, mmalcolm crawford wrote:
On Nov 18, 2008, at 10:01 AM, Brian Stern wrote:
OK Erik, I'll bite. What you describe above is correct as far as
it goes. However, when you say all the memory management is
handled in one place, of course it's two. The object has to be
released. The normal place to release objects is in their owner's
dealloc method, and this also applies to outlets.
This is standard (best) practice for memory management. It's not
clear what the problem is here.
The only difference with outlets is that, if you don't follow best
practice, you have to spend some time thinking about whether or not
you have to release in dealloc (more on this below).
There are competing issues. Following this best practice forces me to
add public properties for all my outlets that my code never uses.
This violates encapsulation and seems wasteful and error-prone.
That's the reason I didn't do this earlier. The one little paragraph
in the documentation that addresses this says I 'should' do it this
way but doesn't explain why. I'll point out that the paragraph that
explains memory management of outlets on Mac OS X on that page is half
the length of the iPhone paragraph, and I'd maintain that the iPhone
paragraph isn't long enough.
However, UIViewController has the ability to unload its view outlet
in response to a memory warning. Any subclass should also release
its outlets in response to the memory warning, if the base class
releases its view, but not otherwise. So now there are three
places to manage the memory of these outlets. The problem is that
the base class doesn't always release its view in response to a
memory warning and as far as I can tell the subclass has no clean
way of telling if the view will be released or has been released.
That's the problem.
You're shifting the goalposts; this is not the problem you
originally described.
It's not me who has shifted the goalposts. The whole playing field
was moved out from under me when it was decided to retain outlets by
default, which is different from how this all works on Mac OS X.
I'll admit that I was confused and probably a few other things a few
days ago when I discovered that a huge memory leak was caused by
outlets being retained behind my back. And then I got a second kick
in the shorts when I read your post pointing out that outlets need to
be released in didReceiveMemoryWarning, which hadn't occurred to me
was a side effect of their being retained.
In fact there have been several problems: You didn't understand the
documentation as written; in testing the implementation of outlets
you made a fundamental mistake; and -- as noted in my original
message in this sub-thread -- the "situation" with outlets has
heretofore been "a mess".
You can add to your list of problems 'insufficient documentation and
education of memory management of outlets.' If you want to believe
that I'm just one yokel developer who can't read and understand the
documentation that's your right. I'm sure I'm not the only one.
To reiterate points that Jon and Joar have made:
You shouldn't have to think about something as mundane as "how do I
manage memory for outlets?". There are far more interesting issues
for a programmer to spend their time on.
I couldn't agree with you more.
This is the reason for proposing a new "best practice" that will
address all situations simply and easily. *If* you know what you're
doing -- and your "experiment" has shown that even relatively
experienced developers may sometimes not "know what they're doing"
-- then it is perfectly possible to deviate from the suggested
pattern, but you then do this at your own risk.
I do, though, have to apologise for introducing a wrinkle (the
problem of UIViewController's response to memory warnings) and then
providing an incorrect solution. I managed to mistake a question
from some time ago for the answer -- mainly because I never received
an answer. I have now and can relay part of it (note to self: <rdar://problem/5834347
>).
I guess even 'relatively experienced developers may sometimes not
"know what they're doing"'
There are several issues:
The template clearly indicates what should be done:
Obviously the client code can't touch _view or self.view in
didReceiveMemoryWarning. That's why I said upthread that there's no
clean way for the client code to tell if the view will be unloaded or
has been unloaded.
In theory, you should simply check whether the view has a superview:
but since _view is declared as @package, you can't do that.
You could invoke 'view':
but this has the disadvantages that (a) in some situations it will
cause the view to be loaded before it is subsequently unloaded, and
(b) it isn't future proof.
self.view will always be non-nil.
This is why I 'shifted the goalposts.' There are many issues related
to memory management of outlets on iPhone. Suggesting that everyone
just follow your best practice described at the top obviously isn't
sufficient.
This leaves us for now with two solutions:
(a) Greg's (override setView:) which is more future-proof but is in
many respects academically unsatisfying.
(b) For non-top-level-object, specify an assign attribute for the
property -- and risk dangling pointers.
The override of setView is very similar to the viewDidUnload callback
that I proposed as a solution for this. It has its own further
issues. UIViewController calls [setView:nil] from its dealloc method
so the subclass has to be prepared for this. What I've done is to add
all the public retain properties for all the outlets. Additionally
I've added a
-(void)releaseOutlets
method that uses the properties and sets them all to nil. I call this
method from my subclass's dealloc method and setView: override. That
way I only have one place to write the code that releases all the
outlets.
Brian
--
Brian Stern
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden