2013-04-27 159 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'返回一個值** AND **有一個完成處理程序嗎?返回值會是這樣的:return handler(deserializedDict); – 2013-04-27 17:12:49

+1

編號'getCurrentClient'在實際的異步請求完成之前返回。您需要更新結構以支持使用回調,而不是使用'getCurrentClient'的返回值。 – Tim 2013-04-27 18:44:25

+0

真棒,這幫了我很多。謝謝,蒂姆。 – 2013-12-26 02:49:36