views:

21

answers:

1

I am trying to setup an NSInovcation system to launch selectors into background threads using performSelectorInBackground: - So far everything is successful when running the system on instance methods (-), but I also want to support class methods (+). I have adjusted my code to provide an invokeInBackgroundThread for both types of class and everything worked except for one problem. When the class methods are invoked I get my console flooded with "autoreleased with no pool in place" messages. No idea what is causing it. The code which is based off the DDFoundation open source project is shown below.


@implementation NSObject (DDExtensions)
...
+ (id)invokeInBackgroundThread
{
    DDInvocationGrabber *grabber = [DDInvocationGrabber invocationGrabber];
    [grabber setInvocationThreadType:INVOCATION_BACKGROUND_THREAD];
    return [grabber prepareWithInvocationTarget:self];
}

- (id)invokeInBackgroundThread
{
    DDInvocationGrabber *grabber = [DDInvocationGrabber invocationGrabber];
    [grabber setInvocationThreadType:INVOCATION_BACKGROUND_THREAD];
    return [grabber prepareWithInvocationTarget:self];
}
...

...
- (void)forwardInvocation:(NSInvocation *)ioInvocation
{
    [ioInvocation setTarget:[self target]];
    [self setInvocation:ioInvocation];

 if (_waitUntilDone == NO) {
  [_invocation retainArguments];
 }

    if (_threadType == INVOCATION_MAIN_THREAD)
    {
        [_invocation performSelectorOnMainThread:@selector(invoke)
                                      withObject:nil
                                   waitUntilDone:_waitUntilDone];
    } else {
        [_invocation performSelectorInBackground:@selector(invoke)
                                  withObject:nil];
 }
}
...

+(void)doSomething;
[[className invokeOnBackgroundThread] doSomething];
+1  A: 

Main thread has autorelease pool by default, if you start extra thread - it's your job to create the pool. Actually, nothing complicated here, just

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// Work...
[pool release];

Also, if you have a lot of threads, I'd suggest you to take a look at NSOperation instead of running threads with [performSelectorInBackground]. NSOperation (with wrapping queue) is more flexible solution for such tasks.

Gobra