iOS 5+ - 在执行请求时冻结主线程执行

时间:2013-04-10 14:20:34

标签: ios multithreading rest request

我正在iOS应用程序中实现一些RESTful API,我目前正在处理登录功能。用户输入用户名和密码,当按下登录时会发生以下情况:

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

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

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

如何首先隐藏/显示所有隐藏/显示内容(如显示活动指示符和“登录”标签),然后开始授权过程,等待它完成,然后才转到另一个视图控制器或显示警报或东西?

2 个答案:

答案 0 :(得分: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.
}];

这样你就不会在网址加载过程中阻塞主线程。

答案 1 :(得分:0)

在迈克关于使用背景并获得我认为您正在寻找的功能的答案的基础上,可以做到以下几点。

在点击登录按钮上绑定您的操作以激活方法。这仍然是前景。立即调度您的应用程序逻辑以处理消息。如果需要,您的后台方法(performAuthCall)仍然可以运行同步。

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

此外,在您调度的同一方法中,将bool设置为阻止呼叫,使按钮变灰,启动活动控制。主线程仍然可以正常工作,但是你对诸如shouldPerformSegueWithIdentifier之类的项目的拦截将允许你阻止不受欢迎的导航。

当你的performAuthCall完成后,让它在主线程上执行一个选择器来设置bool,以便方法可以开始移动,取消项目,停止活动控制。它还确定您是否启动警报(错误密码)或强制segue进入下一个控制器。

记住 - UI需要在主线程中的所有内容和所有额外的逻辑(比如执行类似登录调用的操作)应该在后台线程中。