EOG
EOG

Reputation: 1747

Is this the right way to use NSAutoreleasePool?

I'm new to Objective-C and I'm not sure if I'm using NSAutoreleasePool the right way.

  1. If I want to use autorelease only one time I use:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt];
    sliderLabel.text = newText;
    [pool release]; //newText will be released
    
  2. If I want to use autorelease several times I use:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt];
    sliderLabel.text = newText;
    [pool drain]; //newText will be released
    newText = [NSString stringWithFormat:@"%d", prograssAsInt];
    sliderLabel.text = newText;
    [pool drain]; //newText will be released
    newText = [NSString stringWithFormat:@"%d", prograssAsInt];
    sliderLabel.text = newText;
    [pool release]; //newText will be released
    

Is this OK? Are there any memory leaks?

Upvotes: 1

Views: 1704

Answers (4)

Amy Worrall
Amy Worrall

Reputation: 16337

Normally, if you're on the main thread and you're not using a huge loop of resource intensive code, you don't ever need to create your own autorelease pools. Just use the default one that's created for you.

You only need to make your own if you're multithreading or if you're doing a memory intensive long-running loop (which you probably shouldn't do on the main thread anyway).

Upvotes: 3

kennytm
kennytm

Reputation: 523184

(2) is not OK. -drain and -release are equivalent (in a ref-counting environment), and aftering -draining the autorelease pool is deallocated. So you will double-release the autorelease pool object and crash the program.

Even before ARC, unless you are working in a very tight memory budget, it's atypical to create an NSAutoreleasePool besides the boilerplate main(). The objects -autoreleased into the pool will be released after every tick of NSRunLoop anyway. There will be no memory leak if you strictly follow the ownership transfer rules (see Understanding reference counting with Cocoa and Objective-C).

And with ARC turned on you don't even need to care about this — the compiler will insert the -retain and -release at the right place for you.


Also, if sliderLabel.text is marked as @property(retain) (or (strong)), then releasing the autorelease pool in (1) will not release the newText because that object has a new owner now.

Upvotes: 3

Richard J. Ross III
Richard J. Ross III

Reputation: 55533

Sorry to say this, but RTFM. After -drain is called, the pool deallocates itself, so that it is invalid.

And, currently, in objective-c with Apple's LLVM compiler, there is a language addition called @autoreleasepool that works with both ARC and non-ARC code, that you can leverage as such:

@autoreleasepool {
    // code that will automatically have any -autoreleased variables cleaned up.
} 

Upvotes: 3

Mark Granoff
Mark Granoff

Reputation: 16938

I would say the calls to [pool drain] are unnecessary. I've never seen them used in practice. I suppose if you are allocating huge amounts of memory inside the autorelease pool, it might be necessary. But in the typical case, I would think not.

You will want to start using the following construct, by the way, for autorelease pools:

@autoreleasepool {
    ... your code ...
}

This is, apparently, much more efficient than the "old" way (the way you are doing it). Functionally, it's the same, but internally it performs much better. There was something about this in recent Xcode/iOS release notes.

Upvotes: 3

Related Questions