AFNetworking不会在块内同步返回数据

时间:2012-08-29 21:03:22

标签: iphone ios xcode json afnetworking

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

这是我的方法:

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您的方法无法使用其当前设计。

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

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