views:

736

answers:

3

When the view property of a UIViewController is accessed, it first checks to see if it's got an existing view, and returns that. If not, it loads its nib or calls -loadView.

When a controller receives a -didReceiveMemoryWarning message, the default behavior is to remove that cached view (assuming it's not in use at the time).

If I override -didReceiveMemoryWarning, how can I determine whether the view has been cleared? My understanding is that the default implementation checks to see if self.view.superview == nil. If so, it clears the cached view. Of course, it first checks to see if there is a cached view, and if not, it does nothing. However, I, as a subclass, can't call self.view.superview, for if there isn't a view, it'll generate one.

So, how do I figure out if _view exists? (I can't just look at _view; I get linking errors when building for the device).

A: 

You could use object_getIvar() to get at the value without going through the accessor. In essenvce it lets you get at _view without needing to link against it. On the other hand it has the potential to break if the actual ivar goes away or is renamed. Traditionally that was never a real concern, but the iPhone uses the modern runtime which does not suffer from fragile base class issues, so Apple might feel more inclined to make those sorts of changes.

Louis Gerbarg
+4  A: 

I think in your situation it's best to do something like:

- (void)setView:(UIView *)view
{
    if (!view)
    {
         // Clean up code here
    }

    [super setView:view];
}
Mike Abdullah
This seems somewhat fragile (it relies on Apple always using their own accessors), but does seem to work. Thanks!
Ben Gottlieb
I agree that it's slightly fragile, but there is nothing else documented, and is certainly less fragile than accessing ivars directly
Mike Abdullah
+3  A: 

Since iPhone OS 3.0, you can use the isViewLoaded method to see if a view is loaded.

Andreas