处理AFNetworking2.0异步HTTP请求

时间:2014-04-08 23:18:18

标签: objective-c post asynchronous ios7 afnetworking-2

我对异步编程的概念很陌生,但我得到了它的一般要点(事情在后台运行)。

我遇到的问题是我有一种利用AFNetworking 2.0发出HTTP帖子请求的方法,它在大多数情况下都有效。

但是,我无法弄清楚如何在方法返回时让方法实际返回从响应中接收的值,然后THEN从响应中获取值。

-(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!
}

什么是正确的'处理这种情况的方法?我听过使用“回调”的耳语,但在这种情况下,我真的不明白如何实现这一点。

任何指导或帮助都会很棒,欢呼!

2 个答案:

答案 0 :(得分:1)

问题在于,POST异步运行,正如您所指出的那样,所以在实际return属性之前,您正在点击responseValue设置,因为success块稍后运行。在其中放置断点/ 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财产,因为现在您正在使用完成功能块,您可以通过该机制将其传回给您,而不是依靠在类属性上。

答案 1 :(得分:1)

选中此项并使用搜索; - ))

Getting variable from the inside of block

已经有很多重复了!

: - )