On Mon, Apr 27, 2009 at 3:17 PM, Symphonik <[email protected]> wrote: > 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?
Why does -runSomethingThatWillFail: have its own pool? You already have a pool, you don't need a second one. Get rid of that pool and suddenly everything becomes easy. If it really *must* have a pool for some reason, then the retain/autorelease dance is the standard procedure for getting returned objects out of the current pool and into the next one. Think of that error value as a return value, even though it's returned by reference and not by value. Mike _______________________________________________ Cocoa-dev mailing list ([email protected]) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
