views:

83

answers:

1

(I have read Apple's memory management guide, as well as other memory management help here, but am still confused on the following)

What should I do for memory management with convenience methods in a loop? Do I need to explicitly create an autorelease pool and then drain it. Or is it all automagic?

e.g.

for (i=0; i<numFilePaths; i++) {
    // ...
    NSString *componentString = [someString lastPathComponent];
    // ...
}

In this example, I'm repeatedly getting a new string from lastPathComponent. Ignoring for a moment the bad manners in the same thing repeatedly, how should I be handling this memory management situation?

'componentString' is not retained at all, it has a lifespan only within the loop, and is used merely for comparisons with other strings. Thanks for any help.

+5  A: 

The autorelease pool only gets drained when the run loop finishes, usually at the end of a method when control returns to the user. If you find yourself running through a loop many times which will result in the creation of a lot of autoreleased objects (which will build up in memory until your method ends), you might want to create a local autorelease pool and drain it yourself.

You can create and drain a local autorelease pool by just instantiating and releasing a new one.

for (i=0; i<10000; i++) {
  NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
  NSString *aString = [NSString string];
  [pool drain];
}

There is likely a performance hit if you create and release too many pools, so you may want to check for certain number of iterations (say every 100 loops or so) to create and release the pools. There's no set number, so you'll have to do some playing around.

UPDATE: Updated [pool release] to [pool drain] to maintain future compatibility with garbage collection on Marc Charbonneau's recommendation.

Martin Gordon
Apple recommends you call [pool drain] instead of release for future compatibility with garbage collection, although in a managed memory application they do the same thing.
Marc Charbonneau
Wouldn't you want to put the NSAutoreleasePool calls outside the for loop?
Marc W
@Mark - that would defeat the purpose here... the problem was with having a large loop where you wanted to be more aggressive about freeing up memory. I prefer to use specifically allocated instances (if I can) in loops like this and release them at the end of the loops since it performs better.
Jason Coco