Re: Responding to view controller memory warnings (was Re: Outlets / IBOutlet declarations)
Re: Responding to view controller memory warnings (was Re: Outlets / IBOutlet declarations)
- Subject: Re: Responding to view controller memory warnings (was Re: Outlets / IBOutlet declarations)
- From: James Montgomerie <email@hidden>
- Date: Thu, 19 Feb 2009 20:18:42 +0000
Returning to this months-old thread... Apologies for the length of
the mail, I thought it best to summarise what went before.
I suggested that an appropriate implementation for
didReceiveMemoryWarning in a UIViewController subclass would be
On 22 Nov 2008, at 15:58, James Montgomerie wrote:
- (void)didReceiveMemoryWarning
{
if(self.anOutlet && !self.view.superview) {
// Will not call loadView if the view is not loaded, because
// we can assume that if we get past the check for anOutlet
// the view must already be loaded.
self.anOutlet = nil;
}
[super didReceiveMemoryWarning]; // Releases the view if it doesn't
have a superview
}
mmalc looked into it, and said:
On 23 Nov 2008, at 20:10, mmalcolm crawford wrote:
It seems that, for various reasons, the setView: approach is still
preferred.
I left the code in my app as-is, because I didn't fancy changing it
all, and the response didn't indicate (to me, at least) that I was
doing anything unsafe, but after some testing I'm rethinking that.
Is the reason that the setView: approach is preferred that, despite
what the docs and comments in the files say, the superclass'
didReceiveMemoryWarning might /not/ actually release the view, even if
it doesn't have a superview? This would lead to the situation in
which, when the UIViewController is next used, loadView is not called
(because the view is not nil), but my resources /are/ nil, because I
released them in didReceiveMemoryWarning when I saw that the view had
no superview.
That's what my playing around seems to suggest, in the simulator,
calling didReceiveMemoryWarning directly, at least:
- (void)didReceiveMemoryWarning
{
if(self.anOutlet && !self.view.superview) {
NSLog(@"Released");
}
[super didReceiveMemoryWarning];
// accessing the ivar directly to avoid loadView - very much just
for testing purposes!
NSLog(@"View: %p, %@", self->_view, self->_view);
}
produces, when I call didReceiveMemoryWarning directly, with the view
not visible:
2009-02-19 19:56:00.625 MyApp[76455:20b] Released
2009-02-19 19:56:00.626 MyApp[76455:20b] View: 0x43b24c0, <UIView:
0x43b24c0>
Jamie.
For those who didn't follow the original thread, the "setView:
approach" is, by the way:
On Nov 18, 2008, at 1:19 PM, Greg Titus wrote:
The way to handle this is to _not_ respond to memory warnings in
subclasses (at least not for the purposes of view outlet handling -
there may be other non-view memory you want to free up in response
to a memory warning). Instead, implement -setView: in your
UIViewController subclass, and release outlets when the argument is
nil. For example:
- (void)setView:(UIView *)aView;
{
if (!aView) {
self.anOutlet = nil;
self.anotherOutlet = nil;
self.thirdOutlet = nil;
}
[super setView:aView];
}
This will correctly clean up all of your outlets whenever the
UIViewController unloads its view, and not otherwise.
_______________________________________________
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