并非所有NSOperations都返回价值

时间:2013-01-25 14:49:45

标签: ios nsoperation nsoperationqueue

我在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];
    }
}

问题可能是它与并发方法在同一个类中吗?

1 个答案:

答案 0 :(得分:0)

两个想法:

  1. 您还没有向我们展示足够的诊断信息,但是您可能有20个并发操作在您的evals实例变量中进行迭代,并且它们都会更新。这不可能是好事。我可能会建议你可以迭代的[self evaluateVariables:variables]结果的局部变量。请参阅下面的示例。

  2. 当你说只有96个正在运行时,绝对可以肯定吗?是否有可能它们没有按照您将它们添加到队列中的顺序完成?

  3. 所以,我可能会建议:

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