我在NSOperation
:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:20];
for (int i = 0; i<runCount; i++) {
NSInvocationOperation *op =[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(runFormula:) object:frm];
[queue addOperation:op];
}
以下是方法正文:
-(void)runFormula:(NSDictionary *)frm
{
NSMutableString *formula = [[frm objectForKey:kFormulaExpresion] mutableCopy];
NSArray *variables = [frm objectForKey:kVariableArray];
evals = [self evaluateVariables:variables];
for (NSDictionary *var in evals) {
NSString *sym = [var objectForKey:kVariableSymbol];
[formula replaceOccurrencesOfString:sym withString:[[var objectForKey:@"numVal"] stringValue] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [formula length])];
}
//parse formula
double result = [formula evaluateMath];
NSLog(@"formula %@ the result : %f",formula,result);
NSNumber *resNo = [NSNumber numberWithDouble:result];
[self performSelectorOnMainThread:@selector(addNewResult:) withObject:resNo waitUntilDone:NO];
}
问题是,如果我给runCount 100,我只收到大约96个结果......为什么?还有一件事:第一个结果是胡说八道,但其他94-95都没问题。
这是数据汇总方法......
#pragma mark -- data aggregation delegate
-(void)addNewResult:(NSNumber *)nr
{
NSLog(@"index : %i result: %f",currentIndex,[nr doubleValue]);
[[self delegate] didReceiveResult:nr];
resultsArray[currentIndex]=[nr doubleValue];
currentIndex ++;
if ( (currentIndex % percentVal) == 0) {
[[self delegate] percentCompleted];
}
}
问题可能是它与并发方法在同一个类中吗?
答案 0 :(得分:0)
两个想法:
您还没有向我们展示足够的诊断信息,但是您可能有20个并发操作在您的evals
实例变量中进行迭代,并且它们都会更新。这不可能是好事。我可能会建议你可以迭代的[self evaluateVariables:variables]
结果的局部变量。请参阅下面的示例。
当你说只有96个正在运行时,绝对可以肯定吗?是否有可能它们没有按照您将它们添加到队列中的顺序完成?
所以,我可能会建议:
-(void)runFormula:(NSDictionary *)frm
{
NSMutableString *formula = [[frm objectForKey:kFormulaExpresion] mutableCopy];
NSArray *variables = [frm objectForKey:kVariableArray];
NSArray *evals = [self evaluateVariables:variables]; // LOCAL VAR
for (NSDictionary *var in evals) {
NSString *sym = [var objectForKey:kVariableSymbol];
[formula replaceOccurrencesOfString:sym withString:[[var objectForKey:@"numVal"] stringValue] options:NSCaseInsensitiveSearch range:NSMakeRange(0, [formula length])];
}
//parse formula
double result = [formula evaluateMath];
NSLog(@"formula %@ the result : %f",formula,result);
NSNumber *resNo = [NSNumber numberWithDouble:result];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self addNewResult:resNo];
}];
}
注意,在上面的代码块中,就风格问题而言,如果我正在使用操作,那么在调度回主队列时我会保持在NSOperationQueue
比喻中。没关系,我不认为,但感觉更加一致。
同样,在初始调用中,如果它变得更具可读性,您可以始终考虑块变化。如果您想查看识别各个操作的诊断信息,您也可以记录i
,这样您就可以确保它们都在运行:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:20];
for (int i = 0; i < runCount; i++) {
[queue addOperationWithBlock:^{
NSLog("started %d", i); // log i if you want to see that diagnostic information, too
[self runFormula:frm];
NSLog("finished %d", i);
}];
}