AFNetworking 未在块内同步返回数据
Posted
技术标签:
【中文标题】AFNetworking 未在块内同步返回数据【英文标题】:AFNetworking not returning data synchronously inside a block 【发布时间】: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;
【问题讨论】:
【参考方案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
显然,您必须更改调用它的人的设计,因为它不会以您指定的方式返回值。也许有更好的解决方案,但我认为这是它工作所需的设计类型。
【讨论】:
以上是关于AFNetworking 未在块内同步返回数据的主要内容,如果未能解决你的问题,请参考以下文章