2

で数式を実行してい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 の結果しか得られないことです...なぜですか? もう 1 つ: 最初の結果はナンセンスですが、他の 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];
    }
}

問題は、これが並行メソッドと同じクラスにあることでしょうか?

4

1 に答える 1

0

2つの考え:

  1. これを診断するのに十分な情報は示されていませんが、evalsインスタンス変数を反復処理する同時操作が 20 ある可能性があり、それらはすべて更新されます。それは良くありません。[self evaluateVariables:variables]繰り返し処理できる結果のローカル変数を提案するかもしれません。以下の私のサンプルを参照してください。

  2. 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);
    }];
}
于 2013-01-28T20:51:46.980 に答える