我目前正在我的一款iPhone应用中使用AFNetworking。这是一个非常方便的库来进行异步调用。但是,我在我的应用程序中遇到了需要从服务器获取数据以继续前进的情况。所以我想出了这种等待回复的方式。
MyAFNetworkClient *httpClient = [MyAFNetworkClient sharedClient];
NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:path parameters:nil];
__block int status = 0;
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"notificationName" object:JSON];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){
@throw error.userInfo;
status = 2;
NSLog(@"Error... Status Code 2");
}];
[httpClient enqueueHTTPRequestOperation:operation];
[httpClient.operationQueue waitUntilAllOperationsAreFinished];
while (status == 0)
{
// run runloop so that async dispatch can be handled on main thread AFTER the operation has
// been marked as finished (even though the call backs haven't finished yet).
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate date]];
}
使用这段代码,我可以等待服务器的响应,并能够继续进行。这似乎解决了我的问题,但是,不确定这是否是一个很好的方式来打电话。如果是,是否有一个好的设计原则,我可以保持代码通用并在我的应用程序中使用它。
谢谢
答案 0 :(得分:12)
永远不要阻止主(UI)线程。也就是说,永远不要同步网络。
在您的请求加载的整个时间内,您的应用程序似乎已冻结 - 完全无法响应触摸和系统事件,直到请求完成。
至少,显示一个加载模式,在请求完成之前不会解除。更好的是,如果可能的话,使用户可以在加载请求时正常交互应用程序。
你在这里所拥有的技术可能会起作用,但对于真正的应用来说这是不可接受的。
答案 1 :(得分:0)
对于那些遇到异步调用并且想要等待数据返回主线程以执行其他操作的所有人,这可能会有一点帮助
情景:
用户身份验证:用户输入用户名,密码并尝试登录。
解决方案:向他们展示加载模式以告诉他们幕后发生的事情,一旦你收到回复,就可以进入主线程,如下所示。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
// perform next steps....
});
}
感谢@matt提供有关在这种情况下需要做什么的提示。