Reputation: 5590
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 *)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
}
Upvotes: 0
Views: 2989
Reputation: 55573
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];
}
}
Upvotes: 1
Reputation: 1086
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):
Upvotes: 1