2013-04-27 9 views
8

補完ハンドラから値を返すメソッドを呼び出す必要があります。このメソッドは非同期に実行され、メソッドのすべての本体が実行される前に値を返すことは望ましくありません。ここで私が達成しようとしているものを説明するためにいくつかの障害のあるコードは次のとおりです。補完ハンドラと戻り値

// This is the way I want to call the method 
NSDictionary *account = [_accountModel getCurrentClient]; 

// This is the faulty method that I want to fix 
- (NSDictionary *)getCurrentClient 
{ 
    __block NSDictionary *currentClient = nil; 
    NXOAuth2Account *currentAccount = [[[NXOAuth2AccountStore sharedStore] accounts] lastObject]; 

    [NXOAuth2Request performMethod:@"GET" 
         onResource:[NSURL URLWithString:[NSString stringWithFormat:@"%@/clients/%@", kCatapultHost, currentAccount.userData[@"account_name"]]] 
        usingParameters:nil 
         withAccount:currentAccount 
       sendProgressHandler:nil 
        responseHandler:^ (NSURLResponse *response, NSData *responseData, NSError *error) { 
         NSError *jsonError; 

         currentClient = [NSJSONSerialization JSONObjectWithData:responseData 
                     options:kNilOptions 
                      error:&jsonError]; 
        }]; 

    return currentClient; 
} 

私はNXOAuth2Requestが完了するまでgetCurrentClientメソッドが値を返すようにしたくありません。リクエストのレスポンスハンドラ内で現在のクライアントを返すことはできません。では、私の選択肢は何ですか?

答えて

19

getCurrentClientを変更して、値を返す代わりに完了ブロックを取得する必要があります。例えば

-(void)getCurrentClientWithCompletionHandler:(void (^)(NSDictionary* currentClient))handler 
{ 
    NXOAuth2Account *currentAccount = [[[NXOAuth2AccountStore sharedStore] accounts] lastObject]; 

    [NXOAuth2Request performMethod:@"GET" 
         onResource:[NSURL URLWithString:[NSString stringWithFormat:@"%@/clients/%@", kCatapultHost, currentAccount.userData[@"account_name"]]] 
        usingParameters:nil 
         withAccount:currentAccount 
       sendProgressHandler:nil 
        responseHandler:^ (NSURLResponse *response, NSData *responseData, NSError *error) { 
         NSError *jsonError; 

         NSDictionary* deserializedDict = [NSJSONSerialization JSONObjectWithData:responseData 
                         options:kNilOptions 
                          error:&jsonError]; 
         handler(deserializedDict); 
       }]; 
} 

それは、ネットワーク要求が別のスレッドにディスパッチされながらgetCurrentClientは、すぐに戻りますことを覚えておくことが重要です。レスポンスハンドラを使用してUIを更新する場合は、ハンドラを持つ必要があることを忘れないでください。run on the main thread

+0

私は 'getCurrentClient'が値を返し、**完了ハンドラを持っていますか?戻り値は次のようなものになります。return handler(deserializedDict); –

+1

いいえ 'getCurrentClient'は、実際の非同期リクエストが終了する前に返します。 'getCurrentClient'が使われる戻り値の代わりにコールバックを使うように構造体を更新する必要があります。 – Tim

+0

すごく助かりました。ありがとう、ティム。 –

関連する問題