Perform Method With int Return Value in Background Thread
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.
精彩评论