• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Autorelease and passing by reference in background threads
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: Autorelease and passing by reference in background threads
      • From: Michael Ash <email@hidden>
    • Re: Autorelease and passing by reference in background threads
      • From: Greg Parker <email@hidden>
  • Prev by Date: NSTableViews Load Progressively.
  • Next by Date: click in NSButtonCell in NSTableView without selecting table row?
  • Previous by thread: Re: NSTableViews Load Progressively.
  • Next by thread: Re: Autorelease and passing by reference in background threads
  • Index(es):
    • Date
    • Thread