Ios Swift:DismissViewController()和Dismissing键盘出现线程问题
我正在向我的服务器发送一些数据,收到响应后,我将关闭视图控制器。在viewController的ViewWillEnglishe()中,我尝试关闭键盘 如果presentER viewController不是根视图控制器,则我会收到异常“[UIKeyboardTaskQueue WaitUntillallTasksRefinished]只能从主线程调用。”。我曾尝试调用一个函数,该函数先关闭键盘,然后关闭viewcontroller(不再需要ViewWillEnglishe()),但它也有同样的问题 代码: //在显示的viewcontroller中Ios Swift:DismissViewController()和Dismissing键盘出现线程问题,ios,multithreading,swift,uiviewcontroller,uikeyboard,Ios,Multithreading,Swift,Uiviewcontroller,Uikeyboard,我正在向我的服务器发送一些数据,收到响应后,我将关闭视图控制器。在viewController的ViewWillEnglishe()中,我尝试关闭键盘 如果presentER viewController不是根视图控制器,则我会收到异常“[UIKeyboardTaskQueue WaitUntillallTasksRefinished]只能从主线程调用。”。我曾尝试调用一个函数,该函数先关闭键盘,然后关闭viewcontroller(不再需要ViewWillEnglishe()),但它也有同样的
override func viewWillDisappear(animated: Bool)
{
super.viewWillDisappear(animated)
self.view.endEditing(true)
}
func manage_response(//)
{
run_on_background_thread
{
self.parse(//)
run_on_main_thread
{
self.presented_controller.dismissViewControllerAnimated(true, completion: nil)
}
}
}
代码:
//在presentER viewcontroller中
override func viewWillDisappear(animated: Bool)
{
super.viewWillDisappear(animated)
self.view.endEditing(true)
}
func manage_response(//)
{
run_on_background_thread
{
self.parse(//)
run_on_main_thread
{
self.presented_controller.dismissViewControllerAnimated(true, completion: nil)
}
}
}
我所看到的一切都表明这是如何处理这种情况。只有当我显示了一个键盘,并且试图用它各自的viewcontroller消除它时,问题才存在
编辑:
我用于线程的尾部方法函数的语法:
func run_on_background_thread(code: () -> Void)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), code)
}
func run_on_main_thread(code: () -> Void)
{
dispatch_async(dispatch_get_main_queue(), code)
}
解决方案:
我已经追查到了这个问题。这种情况与先前的想法不同。当我试图显示UIAlertController(通过presentViewController)时会发生这种情况,因为查询没有返回正确的数据/凭据
run_on_main_thread
{
if let controller = visibleViewController() //recursive
{
controller.view.endEditing(true)
controller.presentViewController(alert, animated: true, completion: nil)
}
}
您应该尝试以以下方式在主队列中消除它:
dispatch\u async(dispatch\u get\u main\u queue()){
self.presented\u controller.dismissViewControllerAnimated(真,完成:无)
}
您的总体思路是正确的,但您发布的是伪代码。魔鬼在于细节。如果您收到该错误消息,那么您的代码在某个地方从后台线程进行UIKit调用
NSThread有一个类方法isMainThread()。您可以使用它来检查后台运行的代码。问题在于显示UIAlertViewController。此逻辑/代码将解决此类问题:
run_on_main_thread
{
if let controller = visibleViewController() //recursive
{
controller.view.endEditing(true)
controller.presentViewController(alert, animated: true, completion: nil)
}
}
后台线程上的run_和主线程上的run_定义在哪里?我的错。它们在助手/便利函数文件中全局定义。现在包括在内。注意:在整个相当复杂的应用程序中,只有当键盘出现问题时,它们才能完全正常工作。只需输入manage_response()和parse()的参数。我将使用用于在主线程上运行和在后台线程上运行的后续函数调用进行更新我猜您在某个地方有一个错误的假设。你有一个完成块,你认为它正在主线程上执行,但它不是,它正在BG线程上运行。在该完成块中,您正在执行UI代码。损坏已经发生,并且您发布的代码不是问题的根源。在所有完成块/处理程序中调用
NSThread.isMainThread()
all,查看主线程上运行的代码和未运行的代码。我已经跟踪了该问题。这种情况与先前的想法不同。当我试图显示UIAlertController(通过presentViewController)时会发生这种情况,因为查询没有返回正确的数据/凭据。在主线程上运行{如果let controller=visibleViewController()//递归{controller.view.endEditing(true)controller.presentViewController(警报,动画:true,完成:nil)}}如果您已经解决了问题,您应该发布问题的答案并接受。我就是这么做的,这给了我一个例外。即使您使用dispatch_async而不是dispatch_sync,dispatch_sync?dispatch_sync有很多缺点;当使用UI时,通常会有许多更新异步发生,所以我个人认为这是一个错误的做法。