2013-04-27 121 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