Autorelease and passing by reference in background threads
Autorelease and passing by reference in background threads
- Subject: Autorelease and passing by reference in background threads
- From: Symphonik <email@hidden>
- Date: Mon, 27 Apr 2009 12:17:26 -0700
All,
I am using a couple of methods that use NSError ** pointers to
communicate error conditions. These methods run on background threads
and so have their own autorelease pools set up. I pass an NSError
pointer down a couple of method calls -- by the time it comes back up,
it has been dealloc'd by the autorelease pool. A simple example (this
will run if you want to try it for yourself):
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self performSelectorInBackground:@selector(runBackgroundProcess)
withObject:nil];
}
- (void)runBackgroundProcess {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSError *error = nil;
[self runSomethingThatWillFail:&error];
if(error) {
NSLog(@"error: %@", error); // <==== CRASH HERE,
EXC_BAD_ACCESS due to bogus pointer
}
[pool release];
}
- (void)runSomethingThatWillFail:(NSError **)error {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *directoryContents = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:@"/BOGUS" error:error];
[pool release];
}
So I crash in runBackgroundProcess since the error is getting wiped by
the local autorelease pool. Okay, so I'll retain it...
- (void)runSomethingThatWillFail:(NSError **)error {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *directoryContents = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:@"/BOGUS" error:error];
[*error retain];
[pool release];
}
Well, now I have a leak of that NSError object... so I should
autorelease it, I suppose. But that autorelease needs to be outside
the release of the local pool, so it becomes:
- (void)runSomethingThatWillFail:(NSError **)error {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *directoryContents = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:@"/BOGUS" error:error];
[*error retain];
[pool release];
[*error autorelease];
}
Now it works and isn't leaking anymore. But factor in that I have to
do some checking on the existence of the error before I dereference
it, etc... this is becoming some ugly code just to get my NSError back
up the chain.
Am I overthinking this? Anyone else have better suggestions?
Thanks...
Finn
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden