iOS开发出错whose view is not in the window hierarchy!的解决

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.

如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)


一个简单的单窗口App在运行时出现错误:

2016-04-07 14:28:48.411 BlurViewAndPopView[4364:168520] Warning: Attempt to present <UIAlertController: 0x7a0a4e00> on <BlurViewAndPopView.ViewController: 0x797757d0> whose view is not in the window hierarchy!

2016-04-07 14:28:48.935 BlurViewAndPopView[4364:168520] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UIAlertController: 0x7a0a4e00>)

该app的功能是在root VC中弹出一个popover视图,其中包含一个表视图,在点击表视图中的某一行时回调root VC中的闭包,完成改行内容的对话框弹出效果.

分析如下:根据错误信息,可以清楚看到在试图弹出对话框时,root VC不在窗口的继承体系中,这意味着此时root VC不在window中.

查看popover的cellSelect回调方法:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedItem = items[indexPath]
        selectionHandler?(selectedItem: selectedItem)
        dismissViewControllerAnimated(true, completion: nil)
    }

可以看到在调用root VC注册的selectionHandler闭包之后才做的dismissVC的操作,这显然顺序不对!

我们可以这样修改:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedItem = items[indexPath]

        defer {
            selectionHandler?(selectedItem: selectedItem)
        }
        dismissViewControllerAnimated(true, completion: nil)

    }

好了!现在将selectionHandler的回调放到final中,即可保证在root VC中的操作是在dismissVC之后才开始的,这是root VC应该在window的继承体系中了.

上一篇:UITableViewcell autolayout下动态高度


下一篇:PAT乙级 1011. A+B和C (15)