解除视图控制器时出错

时间:2013-11-16 16:54:51

标签: ios objective-c xcode uiviewcontroller

在解雇视图控制器时出现错误,之前没有看到类似的内容,在互联网上没有太多关于它的信息。

继承人的错误: * 断言失败 - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished],/ SourceCache / UIKit / UIKit-2903.2 / Keyboard / UIKeyboardTaskQueue.m:368

一些背景知识,我在保存一些数据后忽略了视图控制器。数据每次都成功保存。另外,我最近更改了日期保存代码,以便在这个方法的主线程上运行,因为我在后台保存了一些问题。

为什么会发生这种情况?

提前致谢。

6 个答案:

答案 0 :(得分:46)

当我在不是主线程的线程(来自网络请求中的回调)上调用-presentViewController:animated:completion:时,我收到了此错误。解决方案是将您的调用调度呈现并解除对主线程的视图控制器:

dispatch_async(dispatch_get_main_queue(), ^{
    //Code that presents or dismisses a view controller here
});

答案 1 :(得分:8)

我在调用摄像机视图时遇到了同样的问题

同一问题的Swift语法:

dispatch_async(dispatch_get_main_queue(), { 
    //Code that presents or dismisses a view controller here  
    self.presentViewController(imagePicker, animated: true, completion: nil)
})

答案 2 :(得分:2)

确保从显示视图中关闭视图控制器。

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html

  

当解雇一个呈现的视图控制器时,   首选方法是让呈现视图控制器解除   它。换句话说,只要有可能,就是相同的视图控制器   提出视图控制器也应该承担责任   解雇它。

答案 3 :(得分:0)

In the target view controller define delegate and protocol:

@class TargetVC;
@protocol TargetVCDelegate <NSObject>
-(void)dismissTargetVC:(TargetVC*)vc;
@end

@interface TargetVC : UIViewController
@property (nonatomic, weak) id<TargetVCDelegate> delegate;
@end

when you done the job at the target view controller call the delegate:
if( [self.delegate respondsToSelector:@selector(dismissTargetVC:)])
{
   [self.delegate dismissTargetVC:self];
}

The implementation of the delegate protocol should be:
-(void)dismissTargetVC:(TargetVC*)vc
{
    [vc dismissViewControllerAnimated:YES completion:nil];

    // you can get relevant data from vc as you still hold reference to it in this block

    // your code ...
}

答案 4 :(得分:0)

您必须确保不仅在主线程上调用present / dissmissViewController,而且还必须确保从同一父viewController调用present / dismissViewController。

例如,有两个navigationController子项。第一个子视图控制器为某个作业呈现第二个子节点,该作业将通过委托(接口)返回。作业完成后,第二个孩子解散自己并调用委托(接口)函数,必须呈现另一个viweController(例如customPopup) - &gt;由于第二个子视图控制器在弹出窗口的状态被调用时没有被解雇,但是当弹出窗口被解除时已经被解除,这就引起了错误。

所以在这种情况下:

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(400 * NSEC_PER_MSEC)), dispatch_get_main_queue(), { () -> Void in
            if let fs = self.scenarios[indexPath.item]{
                fs.loadScenario()
                sDelegate.onSelectedScenario(fs)
            }
        })

会做的。

答案 5 :(得分:0)

如果有人有断言失败问题,那么这里是 Swift 3 的解决方案:

OperationQueue.main.addOperation{
    <your segue or function call>
}

经过测试: Xcode 8.3.2和Swift 3.1