aryaxt
aryaxt

Reputation: 77626

Objective C - ARC, memory management and performSelectorInBackground?

Does ARC no longer require @autoreleasepool on methods invoked in a background thread? The following code suppose to cause a memory leak unless doStuff is wrapped with an @autorelease pool, but when I run instruments it shows that User gets allocated and it gets deallocated at the end of the runloop.

- (IBAction)buttonClicked:(id)sender {
    [self performSelectorInBackground:@selector(doStuff) withObject:nil];
}

- (void)doStuff {
    User *user = [[User alloc] init];
    NSLog(@"%@", user);
}

Upvotes: 3

Views: 255

Answers (3)

Reinhard Männer
Reinhard Männer

Reputation: 15247

I used the following test app:

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
    [self performSelectorInBackground:@selector(doStuff) withObject:nil];
}
- (void)doStuff {
    NSMutableArray *ar = [NSMutableArray array];
    for (int i=0; i<1000000; i++) {
        ar[i] = [NSString stringWithFormat:@"%i", i];
    }
}
@end

Profiling it with the Allocation instrument, I get the following result:
enter image description here
In the 8th line of the call tree, an autorelease pool is used, although I did not set up one in my code. Also, the memory allocated by the background thread seems to be released.
It thus looks as if the background thread has an autorelease pool installed.

EDIT (see comment below):

This does not mean, however, that it is not necessary to install autorelease pools for threads, since the behavior shown above is not documented, as far as I know.

Upvotes: 1

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81868

While there might be hints to an existing autorelease pool in NSThread's implementation there is no such guarantee the documentation. In contrary, the documentation explicitly states otherwise:

performSelectorInBackground:withObject:

The method represented by aSelector must set up the thread environment just as you would for any other new thread in your program.

Threading Programming Guide

If your application uses the managed memory model [MRC and ARC, as opposed to Garbage Collection], creating an autorelease pool should be the first thing you do in your thread entry routine.

Conclusion: While in some specific scenarios there might be an autorelease pool in place it's not advisable to rely on this fact. It's undocumented behavior and can change with every release of the OS or other circumstances. It should generally be avoided in shipping code.

Upvotes: 3

Aehmlo
Aehmlo

Reputation: 930

Actually, that code is supposed to leak memory (under MRC) if you don't add an autorelease (which is pretty much just asking for trouble). But I'm going to answer your question as you asked it anyways.

ARC is supposed to eliminate the need for any sort of memory management (except for blocks and a lot of other gotchas, but whatever). But there are still autoreleased objects. @autoreleasepool is particularly useful in tight loops, etc. There are still pools to drain, you just don't have to add autorelease to objects yourself.

Upvotes: -2

Related Questions