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 (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 arch...@mail-archive.com

Reply via email to