【问题标题】:AFNetworking not returning data synchronously inside a blockAFNetworking 未在块内同步返回数据
【发布时间】:2012-08-29 21:03:21
【问题描述】:

无法使用 AFNetworking 在块内同步接收 JSON。我检查了这个solution。它 在方法结束时总是 nil。

这是我的方法:

- (BOOL)whois:(NSString *)domain withZone: (NSString*) zone
{        
    __block NSString *resultCode;

    NSURL *url = [[NSURL alloc] initWithString:@"myurl"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {     
        resultCode = [JSON valueForKeyPath:[NSString stringWithFormat:@"%@.%@", domain,zone]];  //checked with NSLog, works well              
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation: operation];
    [operation waitUntilFinished];

    if(resultCode == @"available") //nil here
    {
        return YES;
    }
    return NO; 
}

【问题讨论】:

    标签: iphone ios xcode json afnetworking


    【解决方案1】:

    不要创建NSOperationQueue,而是使用[operation start] 启动AFJSONRequestOperation,然后调用[operation waitUntilFinished],它会阻塞主线程直到它完成。那么你的 resultCode 不应该是 nil。

    正如 @mattt 在您链接的帖子中所说,强烈建议不要像这样冻结线程。考虑找出另一种方法来执行此操作,例如从成功块调用您希望继续的新方法,以及从失败块调用不同的失败方法。

    【讨论】:

      【解决方案2】:

      您的方法无法在当前设计下运行。

      - (BOOL)whois:(NSString *)domain withZone: (NSString*) zone
      {        
          __block NSString *resultCode;
      
          NSURL *url = [[NSURL alloc] initWithString:@"myurl"];
          NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
      
          // *** Runs 1st
          AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {     
      
              // *** runs 3rd
              resultCode = [JSON valueForKeyPath:[NSString stringWithFormat:@"%@.%@", domain,zone]];  //checked with NSLog, works well              
          } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
              NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
          }];
      
          // *** Runs 2nd
          NSOperationQueue *queue = [[NSOperationQueue alloc] init];
          [queue addOperation: operation];
          [operation waitUntilFinished];
      
          if(resultCode == @"available") //nil here
          {
              return YES;
          }
          return NO; 
      }
      

      由于块中的材料是第三次异步运行,因此您将无法以当前设计的方式将该值返回给更大的方法。也许使用这样的东西:

      - (void)whois:(NSString *)domain withZone: (NSString*) zone
      {        
      
          NSURL *url = [[NSURL alloc] initWithString:@"myurl"];
          NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
      
          __weak id weakSelf = self;
          // Runs 1st
          AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {     
      
              NSString *resultCode = [JSON valueForKeyPath:[NSString stringWithFormat:@"%@.%@", domain,zone]];  //checked with NSLog, works well       
              [weakSelf receivedResultCode:resultCode];       
          } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
              NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
          }];
      }
      
      - (void) receivedResultCode:(NSString *)resultCode {
          NSOperationQueue *queue = [[NSOperationQueue alloc] init];
          [queue addOperation: operation];
          [operation waitUntilFinished];
      
          if(resultCode == @"available") //nil here
          {
              // do @YES stuff
          }
          else {
              // do @NO stuff
          }
      }
      

      显然,您必须更改调用它的人的设计,因为它不会以您指定的方式返回值。也许有更好的解决方案,但我认为这是它工作所需的设计类型。

      【讨论】:

        猜你喜欢
        • 2011-12-19
        • 1970-01-01
        • 2021-02-23
        • 2013-05-15
        • 1970-01-01
        • 2018-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多