在后台线程中使用int返回值执行方法

时间:2010-12-03 15:03:34

标签: iphone objective-c multithreading

我正在尝试通过在后台线程中执行计算来加快我的应用程序性能,但我在执行此操作时遇到了麻烦。最初我一直在使用

[self performSelectorInBackground:@selector(calculateValue:) withObject:[words objectAtIndex:row]];

当我的选择器是一个void方法时,这很好。但是,我正在尝试做类似的事情,但显然下面的代码无效。

int value = [self performSelectorInBackground:@selector(calculateValue:) withObject:[words objectAtIndex:row]];

非常感谢任何帮助。

更新

这是我目前要走的路线。我不知道如何回调主线程将computeWordValue中的更新值发送到我的cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    int value = [self performSelectorInBackground:@selector(calculateWordValue:) withObject:[wordsSection objectAtIndex:row]];
    NSString *pointValue = [[NSString alloc] initWithFormat:@"Point:%d",value];
    cell.pointLabel.text = pointValue;
 }

-(void)calculateWordValue:(NSString *)word {

  [self performSelectorOnMainThread:@selector(computeWordValue:) withObject:word waitUntilDone:YES];
}

-(int)computeWordValue:(NSString *)word {

  return totalValue; //This will be a randomly generated number
}

2 个答案:

答案 0 :(得分:1)

这是我用来做的一种方式:

 -(void) calculateValue:(id) obj
  {
       // calculate value
       [self performSelectorOnMainThread:@selector(didFinishCalculating:) withObject:[NSNumber numberWithInt:value]];
  }

 -(void) didFinishCalculating:(NSNumber *) val
 {
       // do what you need to do here
 }

这真的不能解决你的问题,我不认为,但至少应该给你一个起点。

更新:

您的新代码向我显示您并不需要在后台执行此操作,只需使用NSDictionary或其他内容缓存该值。这是一个例子:

 -(int) calculateValue:(id) obj
 {
        if ([valuesCache objectForKey:obj] == nil)
        {
            // calculate value
            [valuesCache setObject:[NSNumber numberWithInt:result] forKey:obj];
            return result;
        }
        else
        {
            return [[valuesCache objectForKey:obj] intValue];
        }
 }

答案 1 :(得分:1)

-performSelectorInBackground: ...无法返回您正在调用的方法的值,因为它实际上在选择器执行之前返回。该选择器将在后台线程上执行。

解决方案是异步处理方法的结果,正如Richard指出的那样(他的答案中的方法应该是- (void)didFinishCalculating:(NSNumber*)val,因为只有对象可以在-performSelector: ...调用中传递:

  • 在后台线程上执行选择器
  • 在主线程上调用结果处理程序方法。几乎在任何情况下都应该在主线程上执行此操作,因为Mac OS X和iOS中的某些内容设计为仅在主线程上运行,如GUI更新。