【问题标题】:Perform Method With int Return Value in Background Thread在后台线程中执行具有 int 返回值的方法
【发布时间】:2010-12-03 15:03:34
【问题描述】:

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

[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
}

【问题讨论】:

  • calculateWordValue 的速度有多快/慢,你为什么要尝试在后台运行它?
  • 它执行了很多计算,我只是为了发布而简化了它

标签: iphone objective-c multithreading


【解决方案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];
        }
 }

【讨论】:

  • 我认为它很好地解决了这个问题。当然,问题是您必须在主线程上异步传递结果,最简单的方法是使用performSelectorOnMainThread:
  • 我遵循了这些建议,但我仍然对如何将 int 值传回感到有些困惑。我在上面添加了更多代码以获得更多上下文。
  • 这并没有解决将值返回到主线程的实际问题。 @Joe:见 ogotts 答案。
  • 当你使用委托时,它不会自动在主线程上调用,你必须通过[myDelegate performSelectorOnMainThread:withObject:]在主线程上显式运行它
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    相关资源
    最近更新 更多