iOS5上的performSelectorInBackground没有完成任务



我使用performSelectorInBackground在后台线程上进行计算,以保持主线程对UI任务的响应。这曾经在iOS4上有效,但在iOS5上似乎会出现问题。似乎后台线程有时会成功完成并报告结果,有时它只是无声地死亡,没有异常或其他跟踪。

我想知道iOS5中是否有任何变化导致performSelectorInBackground以不可靠的方式运行?或者是否有一些更好的替代performSelectorInBackground,我不知道?

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self.earningsController performSelectorInBackground:@selector(calculateTotalEarnings:) withObject:[NSNumber numberWithInt:_startAmount]];
[pool drain];
-------------------------------------------------------
-(NSDecimalNumber*)calculateTotalEarnings:(NSNumber*)startAmount
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSDecimalNumber *retValue = [NSDecimalNumber zero];
    @try 
    {
            retValue = [self calculateTotalsWithNumber:startAmount];
        // Post a Notification with calculated totals
         [[NSNotificationCenter defaultCenter] postNotificationName:TOTAL_EARNINGS_CALCULATED object:retValue];
    }
    @catch (NSException * e) 
    {
            NSLog("Exception: %@", [e reason]);  // never gets here
    }
    [pool release];
    return retValue;
}

我不会只关注performSelectorInBackground的变化,而是我会看看你的方法"calculateTotalsWithNumber:"看看它在iOS5下的行为是否不同。如果你的线程偶尔死亡,那么在它的实现中可能有一些错误导致死亡。此外,我会看看你的项目的其他地方,看看是否以某种方式另一个代码可以干扰任务。虽然有可能API稍微改变了一点,导致后台逻辑死亡,但我猜这不太可能,因为数百万的应用程序都在使用它。选择一些更有可能的情况,比如竞争条件或需要某种互斥锁或锁来保护的未受保护的iVar。

我不知道iOS 5下performSelectorInBackground的行为,但在苹果文档中你可以阅读:

performSelectorInBackground: withObject:

在一个新的后台线程上调用接收者的一个方法。

  • (void) performSelectorInBackground: (SEL) aSelector withObject: arg (id)
参数

aSelector

标识要调用的方法的选择器。该方法不应该有一个重要的返回值,并且应该接受一个id类型的参数,或者不接受任何参数。

此外,我只是想分享一种使用Grand Central Dispatch以线程方式执行某些代码的替代方法。一个例子可以说明它的工作方式:

 dispatch_queue_t queue = dispatch_get_global_queue(
                             DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    <your stuff here>
});

检索全局队列,然后向其分派一个"block":

^{
    <your stuff here>
}

块可以看作是一个"闭包"。在objective - c中;在您的例子中,您可以简单地从中调用calculateTotalEarnings。块有两个优点:

  1. 匿名函数;

  2. 访问在调用上下文中定义的局部变量。

所以,你可以试试这种方法,看看情况是否有所改善。

最新更新