From a background thread, I'm jumping back into the main thread to initialize an object (because it uses UIKit), which then gets reused by the background thread (which waits for the initialization), and memory management is not acting the way I suspect.
// called from another bg thread with autorelease pool
- (MyObject*)backgroundMethod {
MyObject* myObject = nil;
[self performSelectorOnMainThread:@selector(initObject:)
withObject:[NSValue valueWithPointer:&myObject]
waitUntilDone:YES];
return myObject;
}
- (void)initObject:(NSValue*)val {
MyObject** objPtr = (MyObject**)[val pointerValue];
*objPtr = [[MyObject alloc] init];
}
This will crash with EXC_BAD_ACCESS when myObject is used in backgroundMethod's caller.
What doesn't crash, however, is if we change the last line of initObject:
to:
*objPtr = [[[MyObject alloc] init] retain];
and the last line of backgroundMethod
to:
return [myObject autorelease];
Why? I thought the [[foo alloc] init]
pattern guaranteed a retain, but it seems like it's getting released around the time backgroundMethod returns it.