2013-04-27 34 views
8

Tôi muốn gọi một phương thức sẽ trả về một giá trị từ trình xử lý hoàn thành của nó. Phương thức thực hiện không đồng bộ và tôi không muốn trả về một giá trị trước khi tất cả phần thân của phương thức đã được thực hiện. Dưới đây là một số bị lỗi mã để minh họa những gì tôi đang cố gắng để đạt được:Trình xử lý hoàn thành và giá trị trả về

// 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; 
} 

Tôi không muốn các phương pháp getCurrentClient để trả về một giá trị cho đến khi NXOAuth2Request đã hoàn tất. Tôi không thể trả lại máy khách hiện tại bên trong trình xử lý đáp ứng của yêu cầu. Thế ý kiến ​​của tôi là gì?

Trả lời

19

Bạn cần thay đổi getCurrentClient để nhận khối hoàn thành thay vì trả lại giá trị.

Ví dụ:

-(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); 
       }]; 
} 

Điều quan trọng là phải nhớ rằng getCurrentClient sẽ trở lại ngay lập tức, trong khi yêu cầu mạng được cử vào thread khác. Đừng quên rằng nếu bạn muốn cập nhật giao diện người dùng bằng trình xử lý phản hồi của mình, bạn cần có trình xử lý run on the main thread.

+0

tôi có thể đặt 'getCurrentClient' trả về giá trị ** VÀ ** có trình xử lý hoàn tất không? Và giá trị trả về sẽ là một cái gì đó như: return handler (deserializedDict); –

+1

No. 'getCurrentClient' trả về TRƯỚC KHI yêu cầu không đồng bộ thực tế đã kết thúc. Bạn cần cập nhật cấu trúc của mình để hỗ trợ bằng cách sử dụng gọi lại thay vì giá trị trả về trong đó 'getCurrentClient' được sử dụng. – Tim

+0

tuyệt vời, điều này đã giúp tôi rất nhiều. Cảm ơn, Tim. –

Các vấn đề liên quan