开发者

Perform Method With int Return Value in Background Thread

开发者 https://www.devze.com 2023-01-28 13:21 出处:网络
I\'m trying to speed up my application performance by performing calculations in background threads but I\'m having trouble doing this. Originally I had been using

I'm trying to speed up my application performance by performing calculations in background threads but I'm having trouble doing this. Originally I had been using

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

which was fine when my selector was a void method. However, I'm trying to do something similar to but obviously the below code isn't valid.

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

Any help is greatly appreciated.

Updated

Here is the route I'm currently going. I don't know how to call back to the main thread to send the updated value from computeWordValue to my cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableVi开发者_StackOverflowew 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
}


Heres a way I use to do it:

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

This really doesn't solve your problem I don't think, but it should at least give you a starting point.

UPDATE:

Your new code shows me that you don't really need to perform this in the background, just cache the value using an NSDictionary or something. Here's an example:

 -(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];
        }
 }


There's no way -performSelectorInBackground: ... could return the value of the method you're calling because it actually returns before the selector was even executed. That selector will be executed on a background thread asap.

The solution is handling the result of your method asynchronously, as Richard pointed out (the method in his answer should be - (void)didFinishCalculating:(NSNumber*)val, because only objects can be passed in -performSelector: ... calls):

  • Perform your selector on a background thread
  • Call your result handler method on the main thread. You should do that on the main thread in just about any case because some things in Mac OS X and iOS are designed to just run on the main thread, like GUI updates.
0

精彩评论

暂无评论...
验证码 换一张
取 消