2013-04-10 70 views
1

我在iOS应用程序中实现了一些RESTful API,目前我正在开发登录功能。用户输入用户名和密码,当按下登录时,会发生以下情况:iOS 5+ - 执行请求时冻结主线程执行

网络活动指示变为可见,文本标签变为隐藏(以及登录按钮),活动指示变为可见,带有文字“签入”的标签。然后:

dispatch_async(queue, 
    ^{[self performSelectorOnMainThread:@selector(performAuthCall) 
    withObject:nil waitUntilDone:YES];}); 

在performAuthCall方法中,视图控制器的属性(一个布尔)被设置为是或否,取决于如果登录成功与否(I使用NSURLConnection的的sendSynchronousRequest)。如果是,则会呈现另一个视图控制器。如果不是,则显示警报。 我没有真正得到我要去的结果,控制器在执行请求之前正在测试成功的登录布尔值,并且我尝试了不同的方法,但是我无法让它正常工作并且不冻结UI。所以,我的问题是:

我怎样才能使所有的隐藏/显示的东西第一(如使可见的活动指标和“登录”标签),然后开始授权过程,等到它完成,只然后继续到另一个视图控制器或显示警报或东西?

+1

不要阻塞主线程。 – 2013-04-10 14:21:59

回答

1

使用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加载过程中主线程。

+0

感谢队友,救了我! :-) – nemesis 2013-04-10 17:14:00

0

要建立在Mike关于使用背景和获得功能的答案上,我认为您正在寻找的是执行以下操作。

将您所拥有的动作绑定在点击登录按钮上以激活一种方法。这仍将处于前景。立即派遣后台您的应用程序逻辑来处理消息。如果需要,您的后台方法(performAuthCall)仍然可以运行同步。

dispatch_async(dispatch_get_global_queue(0, 0), 
        ^{ 
          [self performAuthCall]; 
         }); 

此外,在您调度的同一方法中,设置您的布尔来阻止呼叫,灰色按钮,开始您的活动控制。主线程仍然可以正常工作,但是拦截像shouldPerformSegueWithIdentifier这样的项目将允许您阻止不需要的导航。

当performAuthCall完成后,让它在主线程上执行一个选择器以设置bools,以便方法可以开始移动,不使用项目,停止活动控制。它还决定您是启动警报(错误密码)还是强制继续进入下一个控制器。

记住 - UI需要在主线程中的所有东西,并且所有额外的逻辑(如做类似登录调用的东西)都应该在后台线程中。