Programming Pitfalls: NSAutorelease Pools on iOS 4.X

iOS 5 has brought a lot of quality of life improvements in terms of memory management and the general iOS development workflow, assuming you are on the latest tooling. However, nothing is free and there seems to be a little bit of a pitfall that you might hit if you are testing predominantly on iOS 5.x: iOS 5 seems to deal with autorelease pools a bit differently than 4.

Here’s the situation:

- (void) viewDidLoad {
  [super viewDidLoad];
  [self performSelectorOnMainThread:@selector(yourMagicalMethod) withObject:nil     waitUntilDone:NO];
}

- (void) yourMagicalMethod {
  // do some magical stuff and set some objects to autorelease
}

This will run fine and without complaint on iOS 5. However, on iOS 4 it throws some errors in the log at runtime regarding no autorelease pool being set and leaks every object you set to autorelease in yourMagicalMethod. If that isn’t enough to crash your app, then your app will be in a highly unstable state and will be prone to crashing the next time you do something even somewhat intensive, such as call the camera.

I did some sleuthing with Instruments and found that yes on 4.x those objects are all leaked and yes they are not on 5. Luckily there is an easy solution that doesn’t involve any crazy version checks or (God forbid) compiler macros:

- (void) yourMagicalMethod {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// do some magical stuff and set some objects to autorelease

  [pool release];
}

That’s it. All you need to do is create an autorelease pool in scope and release it. Both iOS 4 and 5 will be happy. I don’t know why this issues exists and I’d love to find out if you do. If you have questions or comments, I am on Twitter and Google+.

Comments are closed.