0

MKNetworkKit を使用して Web サービスからリンクの配列をフェッチし、バックグラウンド スレッドで各応答を解析し、GCD の dispatch_group_t を使用して、すべてのスレッドの処理が完了するまで待機しようとしています。私が立ち往生しているのは、dispatch_group_notify がグループ内のすべてのスレッドが完了するのを待っていない理由を理解できないことです。このコードを実行すると、次のように出力されます。

results count: 0
added into results, count: 1
added into results, count: 2

ディスパッチ グループはそのスレッドで待機していません。dispatch_group_wait も試しましたが、クラッシュしました。MKNetworkKit の NSOperation の使用がこの問題と競合しているかどうかはわかりません。助けてくれてありがとう!

- (MKNetworkOperation *)getABunchOfMovies:(NSArray *)movies onCompletion:(CastResponseBlock)completionBlock onError:(MKNKErrorBlock)errorBlock
{
    MKNetworkOperation *operation;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    block NSMutableArray *results = [[NSMutableArray alloc] initWithCapacity:[movies count]];

    for (NSString *movieTitle in movies) {
        operation = [self operationWithPath:REQUEST_URL(API_KEY, [movieTitle urlEncodedString])];

        [operation onCompletion:^(MKNetworkOperation *completedOperation) {

            dispatch_group_async(group, queue, ^{
                NSDictionary *response = [completedOperation responseJSON];
                id result = [self processResponse:response withMovieTitle:movieTitle];

                @synchronized (results) {
                    [results addObject:result];
                    NSLog(@"added into results, count: %d", [results count]);
                }
            });
        }
                        onError:^(NSError *error) {
                            errorBlock(error);
                        }];

        [self enqueueOperation:operation];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"results count: %d", [results count]);

        // Return array here
        completionBlock(results);
    });

    dispatch_release(group);

    return operation;
}

編集:理由はまだわかりませんが、dispatch_group_enter(group); を使用するように変更すると、そして、dispatch_group_leave(group); と一致させます。完了ブロックの最後に、それは機能します。なぜこれが起こっているのか誰にも分かりますか?

4

1 に答える 1

2

現時点では、MKNetworkKit はキュー完了ハンドラーをサポートしていません。このハックの代わりに、操作の依存関係を追加することを検討する必要があります。

[lastOperation addDependency:op1];
[lastOperation addDependency:op2];

そして、「lastOperation」が完了すると、キューが実際に完了したと想定します。

もう 1 つの方法は、エンジンの「operationCount」キーパスを KVO し、それがゼロになるかどうかを確認することです。

MKNetworkEngine には、ネットワーク アクティビティ インジケーターの表示と非表示を切り替えるコード ブロックがあります。

于 2012-08-13T02:41:47.777 に答える