iOS 5+ - 执行请求时冻结主线程执行
我在iOS应用程序中实现了一些RESTful API,目前我正在开发登录功能。用户输入用户名和密码,当按下登录时,会发生以下情况:iOS 5+ - 执行请求时冻结主线程执行
网络活动指示变为可见,文本标签变为隐藏(以及登录按钮),活动指示变为可见,带有文字“签入”的标签。然后:
dispatch_async(queue,
^{[self performSelectorOnMainThread:@selector(performAuthCall)
withObject:nil waitUntilDone:YES];});
在performAuthCall方法中,视图控制器的属性(一个布尔)被设置为是或否,取决于如果登录成功与否(I使用NSURLConnection的的sendSynchronousRequest)。如果是,则会呈现另一个视图控制器。如果不是,则显示警报。 我没有真正得到我要去的结果,控制器在执行请求之前正在测试成功的登录布尔值,并且我尝试了不同的方法,但是我无法让它正常工作并且不冻结UI。所以,我的问题是:
我怎样才能使所有的隐藏/显示的东西第一(如使可见的活动指标和“登录”标签),然后开始授权过程,等到它完成,只然后继续到另一个视图控制器或显示警报或东西?
使用NSURLConnection sendAsynchronousRequest:::
代替
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(@"response = %@", response);
//do the UI update/segue here once completed.
}];
这样你就不会阻止URL加载过程中主线程。
感谢队友,救了我! :-) – nemesis 2013-04-10 17:14:00
要建立在Mike关于使用背景和获得功能的答案上,我认为您正在寻找的是执行以下操作。
将您所拥有的动作绑定在点击登录按钮上以激活一种方法。这仍将处于前景。立即派遣后台您的应用程序逻辑来处理消息。如果需要,您的后台方法(performAuthCall)仍然可以运行同步。
dispatch_async(dispatch_get_global_queue(0, 0),
^{
[self performAuthCall];
});
此外,在您调度的同一方法中,设置您的布尔来阻止呼叫,灰色按钮,开始您的活动控制。主线程仍然可以正常工作,但是拦截像shouldPerformSegueWithIdentifier这样的项目将允许您阻止不需要的导航。
当performAuthCall完成后,让它在主线程上执行一个选择器以设置bools,以便方法可以开始移动,不使用项目,停止活动控制。它还决定您是启动警报(错误密码)还是强制继续进入下一个控制器。
记住 - UI需要在主线程中的所有东西,并且所有额外的逻辑(如做类似登录调用的东西)都应该在后台线程中。
不要阻塞主线程。 – 2013-04-10 14:21:59