Question

Is this the correct (best?) way to release views retained in viewDidLoad, in iOS 4.x or lower? Is there anything else to consider?

- (void) viewDidUnload
{
    [super viewDidUnload];
    [self releaseViews];
}

- (void) dealloc {
    [self releaseViews];
    [super dealloc];
}

#define SAFE_RELEASE(a) [a release]; a = nil;

- (void) releaseViews {
    SAFE_RELEASE(myView1);
    SAFE_RELEASE(myView2);
    SAFE_RELEASE(myView3);
}
Was it helpful?

Solution

The -dealloc is correct and the -viewDidUnload will work, but typically retained views are only nilled in -viewDidUnload and not released. This seems to be Apple's practice as well and it is what they've baked into the Xcode when you create an auto-generated IBOutlet via the Assistant editor.

For auto-generated IBOutlets, the auto-generated -viewDidUnload looks like this:

- (void)viewDidUnload {
    [self myView1:nil];
    [self myView2:nil];
    [self myView3:nil];
    [super viewDidUnload];
}

Also, from the Apple docs on -viewDidUnload:

The preferred way to relinquish ownership of any object (including those in outlets) is to use the corresponding accessor method to set the value of the object to nil. However, if you do not have an accessor method for a given object, you may have to release the object explicitly

So, there you go. If your outlet has a property associated with it (which they all should anymore), then nil it in -viewDidUnload -- but don't release it. This makes sense when you consider what is actually happening in a synthesized accessor; the code looks something like this:

- (void) setMyView1 : (UIView *) view {
   if (myView1) // the associated IVAR is already set
      [myView1 release];

   myView1 = [view retain];
}

As you can see, setting a synthesize property to nil implicitly releases the retained object.

Also from the docs in regards to -dealloc:

If you implement this method but are building your application for iOS 2.x, your dealloc method should release each object but should also set the reference to that object to nil before calling super.

Unless you are supporting iOS2.x, there is no need to set objects to nil in dealloc.

So, to summarize Apple's docs regarding -viewDidUnload and -dealloc:

  • In -viewDidUnload, nil properties (including IBOutlet properties), but don't release them
  • In -dealloc release properties, but don't nil them (unless building for 2.x).

OTHER TIPS

I'm not sure if it's the best way, but it is correct way to do it if you retained those views in viewDidLoad.

Note that in the dealloc there's no need to set the variables to nil, but it won't hurt doing so so we can use same method for both viewDidLoad and dealloc.

Don't do it in viewDidUnload unless you are recreating them in viewDidLoad, or they are IBOutlets. Good information here and here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top