xcode 关闭视图控制器时出错
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20021107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error when dismissing view controller
提问by Nick Farrant
Getting an error when dismissing a view controller, not seen anything like it before, and not much about it on the internet.
关闭视图控制器时出现错误,以前没有见过类似的东西,在互联网上也没有太多关于它的信息。
heres the error: *Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit/UIKit-2903.2/Keyboard/UIKeyboardTaskQueue.m:368
继承人错误: *断言失败 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit/UIKit-2903.2/Keyboard/UIKeyboardTaskQueue.m:368
a bit of background, i dismiss the view controller after saving some data. the data saves successfully, every time. also, i recently changed the date saving code to run on the main thread for this one method, as i was having some issues saving in the background.
有点背景,我在保存一些数据后关闭了视图控制器。每次都成功保存数据。此外,我最近更改了日期保存代码以在主线程上运行此方法,因为我在后台保存时遇到了一些问题。
any ideas why this is happening?
任何想法为什么会发生这种情况?
Thanks in advance.
提前致谢。
回答by Simon Goldeen
I recieved this error when I was calling -presentViewController:animated:completion:
on a thread that was not the main thread (from a callback in a network request). The solution is to dispatch your calls to present and dismiss view controllers to the main thread:
当我调用-presentViewController:animated:completion:
一个不是主线程的线程(来自网络请求中的回调)时,我收到了这个错误。解决方案是将您对呈现和关闭视图控制器的调用分派到主线程:
dispatch_async(dispatch_get_main_queue(), ^{
//Code that presents or dismisses a view controller here
});
回答by Esqarrouth
I had the same problem while calling the camera view
我在调用相机视图时遇到了同样的问题
Swift syntax for the same problem:
针对同一问题的 Swift 语法:
dispatch_async(dispatch_get_main_queue(), {
//Code that presents or dismisses a view controller here
self.presentViewController(imagePicker, animated: true, completion: nil)
})
回答by EliGreenfeld
Make sure to dismiss the view controller from the presenting view.
确保从呈现视图中关闭视图控制器。
When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.
当需要关闭呈现的视图控制器时,首选方法是让呈现的视图控制器关闭它。换句话说,只要有可能,呈现视图控制器的同一个视图控制器也应该负责解除它。
回答by EliGreenfeld
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 ...
}
回答by Kvant
You must make sure not only that present/dissmissViewController called on main thread but also you have to make sure that present/dismissViewController is called from the same parent viewController.
您不仅必须确保在主线程上调用present/dismissViewController,而且还必须确保从同一个父viewController 调用present/dismissViewController。
For example there are two navigationController children. First child view controller presents the second child for some job that will return thru a delegate (interface). After the job is done second child dismisses itself and calls to delegate(interface) function with have to present another viweController (for example customPopup) -> that's rises the error since the second child view controller is not dismissed when the present of popup called, but already demised when the dismiss of popup called.
例如,有两个 navigationController 子项。第一个子视图控制器为某些将通过委托(接口)返回的作业呈现第二个子视图。工作完成后,第二个孩子会自行解散并调用委托(接口)函数,并且必须呈现另一个 viweController(例如 customPopup)-> 由于调用弹出窗口时第二个子视图控制器没有被解散,因此会引发错误,但是当弹出弹出窗口被调用时已经死亡。
So in this case:
所以在这种情况下:
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)
}
})
will do.
会做。
回答by Atlas_Gondal
If someone is having Assertion Failure issue then here is the solution for Swift 3:
如果有人遇到断言失败问题,那么这里是Swift 3的解决方案:
OperationQueue.main.addOperation{
<your segue or function call>
}
Tested On:Xcode 8.3.2 and Swift 3.1
测试:Xcode 8.3.2 和 Swift 3.1