2014-04-08 4 views
1

비동기 프로그래밍이라는 개념에 익숙하지 않지만, 그것의 일반적인 요지가 있습니다.AFNetworking2.0 비동기 HTTP 요청 다루기

내가 겪고있는 문제는 AFNetworking 2.0을 사용하여 HTTP 게시물 요청을하는 방법이며, 대부분의 경우 작동합니다.

그러나 메서드를 반환 할 때 실제로 응답을받은 값을 반환하는 메서드를 얻는 방법을 알아낼 수 및 다음 응답에서 값을 가져옵니다.

-(int) registerUser 
{ 
self.responseValue = 000; //Notice I set this to 000 at start of method 

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
manager.requestSerializer = [AFJSONRequestSerializer serializer]; 

NSDictionary *parameters = @{ @"Username": @"SomeUsername" }; 

[manager POST:@"http://XXX/register" 
    parameters:parameters 
     success:^(AFHTTPRequestOperation *operation, id responseObject) 
{ 
    NSLog(@"JSON: %@", responseObject); 
    NSError *err = nil; 

    self.responseValue = [[responseObject objectForKey:@"res"] intValue]; 
    //Note: This^ value returns 99 and NSLogs confirm this 
} 
     failure:^(AFHTTPRequestOperation *operation, NSError *err) 
{ 
    NSLog(@"Error: %@", err); 
}]; 

return self.responseValue; //This will return 000 and never 99! 
} 

이 상황을 처리하는 데 '적절한'방법이 무엇입니까? 나는 '콜백'을 사용하는 속삭임을 들었다. 그러나 나는이 상황에서 그것을 구현하는 방법을 정말로 모른다.

모든 안내 또는 도움이 정말 좋을 것입니다.

+0

[블록의 내부로부터 얻는 가변 (http://stackoverflow.com/questions/22919135/getting-variable-from-the-inside-of-block) –

답변

1

문제는 그 그 success 블록은 나중에 실행되기 때문에 당신의 responseValue 속성이 실제로 설정 전에 return 라인 잘 을 타격 있도록, 지적으로 비동기 적으로 POST 실행됩니다. 중단 점/NSLog 문을 입력하면 return 행이 먼저 표시됩니다.

일반적으로 비동기 메서드의 값은 return이지만 완료 블록 패턴을 사용합니다. 예를 들어 다음과 같이

- (void)registerUserWithCompletion:(void (^)(int responseValue, NSError *error))completion 
{ 
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    manager.requestSerializer = [AFJSONRequestSerializer serializer]; 

    NSDictionary *parameters = @{ @"Username": @"SomeUsername" }; 

    [manager POST:@"http://XXX/register" 
     parameters:parameters 
      success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     NSLog(@"JSON: %@", responseObject); 

     int responseValue = [[responseObject objectForKey:@"res"] intValue]; 

     if (completion) 
      completion(responseValue, nil); 
    } 
      failure:^(AFHTTPRequestOperation *operation, NSError *err) 
    { 
      NSLog(@"Error: %@", err); 

      if (completion) 
      completion(-1, err); // I don't know what you want to return if it failed, but handle it appropriately 
    }]; 
} 

와 다음, 당신은 그것을 사용할 수 있습니다

[self registerUserWithCompletion:^(int responseValue, NSError *error) { 
    if (error) 
     NSLog(@"%s: registerUserWithCompletion error: %@", __FUNCTION__, error); 
    else 
     NSLog(@"%d", responseValue); 

    // do whatever you want with that responseValue here, inside the block 
}]; 

// Needless to say, don't try to use the `responseValue` here, because 
// `registerUserWithCompletion` runs asynchronously, and you will probably 
// hit this line of code well before the above block is executed. Anything 
// that is dependent upon the registration must called from within the above 
// completion block, not here after the block. 

주, 나는 당신이 은퇴 좋을 것 당신이 전에했다 responseValue 재산, 이제 완성을 사용하고 있는지 때문에 블록을 사용하면 클래스 속성에 의존하기보다는 해당 메커니즘을 통해 다시 전달됩니다.

+0

의 중복 가능성 좋은 대답, 고마워. 내가 집에 돌아 왔을 때 나는이 기회를 포기할 것이다. 나는 완성 블록에 대해 읽은 바있다. – DeaIss