在取消分配时尝试加载视图控制器的视图... UISearchController

Mor*_*Man 79 ios swift uisearchcontroller

我有创建UISearchController' in my UIVIew'sviewDidLoad`的代码.

 self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.searchBar.delegate = self
        controller.dimsBackgroundDuringPresentation = false
        controller.searchBar.sizeToFit()
        controller.hidesNavigationBarDuringPresentation = false //prevent search bar from moving
        controller.searchBar.placeholder = "Search for song"

        self.myTableView.tableHeaderView = controller.searchBar

        return controller

    })()
Run Code Online (Sandbox Code Playgroud)

在此关闭完成后,此警告将出现在控制台中:

Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x154d39700>)
Run Code Online (Sandbox Code Playgroud)

我不知道我做错了什么.这个类似的问题并不是我的情况(至少我不这么认为).到底是怎么回事?

小智 118

在取消分配之前,必须从其超级视图中删除UISearchController的视图.(猜猜是个bug)

Objective-C的...

-(void)dealloc { 
    [searchController.view removeFromSuperview]; // It works!
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3 ......

deinit {
    self.searchController.view.removeFromSuperview()
}
Run Code Online (Sandbox Code Playgroud)

我在这个问题上挣扎了几个星期.^^

  • 我在`-viewDidLoad`中分配的`UISearchControler`遇到了同样的问题.这肯定是一个错误 - 如果在加载视图之前取消分配`UISearchController`,则会出现此警告.如果我点击搜索字段(从而加载视图),它就不会出现.所以在我的`dealloc`中,我调用`[self.searchController loadViewIfNeeded]`(iOS 9中的新增功能), (22认同)
  • 我要添加@ Leehro的注释,在dealloc中没有必要这样做,你可以在viewDidLoad中执行loadViewIfNeeded. (6认同)
  • @ Leehro的评论是我的答案.它出现为`if #available(iOS 9.0,*){self.searchController?.loadViewIfNeeded()}` (4认同)

Mor*_*Man 36

解决了!这是一个简单的修复.我改变了这段代码

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController = UISearchController()
Run Code Online (Sandbox Code Playgroud)

对此:

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController: UISearchController!
Run Code Online (Sandbox Code Playgroud)

这解决了这个问题.


nij*_*ijm 20

这是适用于我的Swift版本(类似于JJHs答案):

deinit{
    if let superView = resultSearchController.view.superview
    {
        superView.removeFromSuperview()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你不需要`if let`,因为`.removeFromSuperView()`如果`superview == nil`将不会做任何事情. (2认同)

har*_*h_v 11

class SampleClass: UITableViewController, UISearchBarDelegate {

private let searchController =  UISearchController(searchResultsController: nil)

 override func viewDidLoad() {
        super.viewDidLoad()

        searchController.loadViewIfNeeded() // Add this line before accessing searchController
 }

}
Run Code Online (Sandbox Code Playgroud)


Der*_*rek 10

通过完全设置UISearchController 之前向viewDidLoad添加行来设法让我的工作变得很有用:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.rightBarButtonItem = self.editButtonItem()

    if #available(iOS 9.0, *) {
        self.resultSearchController.loadViewIfNeeded()// iOS 9
    } else {
        // Fallback on earlier versions
        let _ = self.resultSearchController.view          // iOS 8
    }
    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.searchBar.sizeToFit()

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    self.tableView.reloadData()

}
Run Code Online (Sandbox Code Playgroud)


Vin*_*ent 7

在Swift2中,由于一个明显的错误,我得到了相同的错误消息:

let alertController = UIAlertController(title: "Oops",
    message:"bla.", preferredStyle: UIAlertControllerStyle.Alert)

alertController.addAction(UIAlertAction(title: "Ok", 
     style: UIAlertActionStyle.Default,handler: nil))

self.presentViewController(alertController, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

由于我自己的愚蠢副本错误,我没有包含self.presentViewController行.这导致了同样的错误.


Mil*_*dic 7

在Swift 2.2版本中,对我有用

deinit {
    self.searchController?.view.removeFromSuperview()
}
Run Code Online (Sandbox Code Playgroud)

我觉得它很有帮助!