2014-09-04 44 views
3

我正在使用NSURLSession向服务器发出请求。为此,我使用自定义的completionHandler创建一个NSURLSessionTask。根据任务结果切换视图swift

根据结果我想切换到另一个视图。但是,当我在完成处理程序中执行此操作时,它不起作用。

NSInternalInconsistencyException 

受此描述完整的错误:

*** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3302.3.1/Keyboard/UIKeyboardTaskQueue.m:374 

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.' 

注:与下面的错误应用崩溃更改视图我用下面的代码

let vc: AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier(viewID) 
self.showViewController(vc as UIViewController, sender: vc) 

什么是错的这里?

+0

@Rob我现在添加了错误。另外,我试图遵循你的建议,但它不起作用。 – pavlag 2014-09-04 23:14:15

+0

我已经使用过它,它没有区别。但可以肯定的是,这应该是我的完成处理程序,对吗? – pavlag 2014-09-04 23:51:24

+0

哦,等一下!我的错。我在调度方法之前调用了showViewController,并且也在调度方法中调用showViewController!我删除了第一个,现在都好了!谢谢@rob – pavlag 2014-09-05 00:04:38

回答

10

主要问题是您的错误消息报告“...只能从主线程调用”。所以你可能已经从后台线程中调用了这段代码(也许是网络请求的完成块或类似的东西)。所以,你必须调度此代码回到主队列:

dispatch_async(dispatch_get_main_queue()) { 
    let vc = self.storyboard.instantiateViewControllerWithIdentifier(viewID) as UIViewController 
    showViewController(vc, sender: self) 
} 

注意,这个代码片断,使一些小的,不相关的更改,即:

  1. 它没有意义指定目标视图控制器作为其自己的发件人。通常你会使用当前视图控制器或一些UIKit控件作为sender

    我指定self作为sender,因为我假设你在源视图控制器中这样做了。或者,如果这是按钮的IBAction,那么您可能会使用IBActionsender参数,而不是源视图控制器。我会失去AnyObject剧组。我知道编译器可能向你提出了这个建议,但它不利于代码的易读性。我建议直接将它铸造成UIViewController

+0

谢谢@rob ...那也适用于我.. – 2014-12-03 09:31:32

1

任何影响用户界面的事情都必须在主线程上运行,而不是在完成处理程序中运行。因此,在您的完成处理程序中,调用performSelectorOnMainThread或使用允许您将该调用放入主线程的其他机制之一。

+0

你可以举一个例子使用那个函数吗? xcode不会以我试过的方式进行编译。 – pavlag 2014-09-04 22:40:13