0

我在后台线程上调用选择器,
选择器周围有 NSAutorelasePool。
我猜我传递给选择器的参数导致了问题。我应该如何处理?

  SEL theSelector;
    NSMethodSignature *aSignature;
    NSInvocation *anInvocation;

    theSelector = @selector(changeColor:forColorString:);
    aSignature = [[animationData class] instanceMethodSignatureForSelector:theSelector];
    anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
    [anInvocation setSelector:theSelector];
    [anInvocation setTarget:animationData];
    // indexes for arguments start at 2, 0 = self, 1 = _cmd                                                                                                                                                                                                                   
    [anInvocation setArgument:&currentColor atIndex:2];
    [anInvocation setArgument:&nsColorString atIndex:3];

    [anInvocation performSelectorInBackground:@selector(invoke) withObject:NULL];
4

2 回答 2

1

当您告诉调用在后台执行调用时,将创建新线程,其中调用是调用的第一个方法。Invoke 不会创建自动释放池,因此在该方法期间自动释放的任何内容都将被泄露。

要解决此问题,请使用包装器方法来执行调用。

- (void)performInvocation:(NSInvocation *)anInvocation {
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    [anInvocation invoke];
    [pool release];
}

//where you were performing the invoke before:
[self performSelectorInBackground:@selector(performInvocation:) withObject:anInvocation];
于 2011-01-14T07:56:51.640 回答
1

除了 ughoavgfhw 所说的,如果您打算将对象设置为参数并传递给后台线程,您还需要调用 [anInvocation retainArguments]。

于 2011-10-28T18:21:17.613 回答