7

dispatch_async結果を返すメソッドで使用しようとしています。dispatch_asyncただし、ブロックを実行する前にメソッドが戻ることがわかりました。このため、期待する結果が得られません。これが私の問題を示すコードです。

-(BOOL) isContactExists {
    BOOL isContactExistsInXYZ = YES;
    UserId *userId = contact.userId;
    dispatch_async(dispatch_get_main_queue(), ^
    {
        iOSContact *contact = [iOSContact contactForUserId:userId];
        if (nil == contact)
        {
          isContactExistsInXYZ = NO;
        }
    });    

    return isContactExistsInXYZ;
}

このメソッドisContactExistsは別の場所で呼び出され、そのメソッドからの応答に基づいて、いくつかの処理を行う必要があります。しかし、毎回、 の値はisContactExistsInXYZ私が期待するものではありません。dispatch_asyncこの状況でどう対処すればよいですか?

4

3 に答える 3

15

ブロックルートに行く場合、メソッドは次のようになる必要があります。

- (void)isContactExistsWithCompletionHandler:(void(^)(BOOL exists)) completion 
{
    dispatch_async(dispatch_get_main_queue(), ^
    {
        BOOL isContactExistsInXYZ = YES;
        UserId *userId = contact.userId;
        iOSContact *contact = [iOSContact contactForUserId:userId];
        if (nil == contact)
        {
          isContactExistsInXYZ = NO;
        }
        completion(isContactExistsInXYZ);
    });
}

そして、あなたはそれをこのように呼んでいます。

[someObject isContactExistsWithCompletionHandler:^(BOOL exists) {
    // do something with your BOOL
}];

また、重い操作をメイン以外のキューに配置することも検討する必要があります。このような。

- (void)isContactExistsWithCompletionHandler:(void(^)(BOOL exists)) completion 
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);
    dispatch_async(queue, ^
    {
        BOOL isContactExistsInXYZ = YES;
        UserId *userId = contact.userId;
        iOSContact *contact = [iOSContact contactForUserId:userId];
        if (nil == contact)
        {
          isContactExistsInXYZ = NO;
        }
        dispatch_async(dispatch_get_main_queue(), ^
        {
            completion(isContactExistsInXYZ);
        });
    });
}
于 2013-10-22T20:21:17.180 に答える
3

その理由はdispatch_async(dispatch_get_main_queue(), ^、実行が完了するまで待機しないためです。あなたはおそらくそこにあるものを台無しにしています。通常、これは、他のスレッドでダウンロードされる他のサーバー コンテンツと共に UI を非同期的に更新するために使用されます。dispatch_sync代わりに使用してみてください 。

于 2013-10-22T18:25:17.060 に答える