ios 试图在解除分配时加载视图控制器的视图... UISearchController

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32282401/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:26:39  来源:igfitidea点击:

Attempting to load the view of a view controller while it is deallocating... UISearchController

iosswiftuisearchcontroller

提问by MortalMan

I have code that creates a UISearchController' in my UIVIew'sviewDidLoad`.

我有创建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

    })()

Right after this closure finishes, this warning appears in the console:

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

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

I don't get what I am doing wrong. This similar questionis not really my situation (At least I don't think so). What is going on?

我不明白我做错了什么。这个类似的问题并不是我真正的情况(至少我不这么认为)。到底是怎么回事?

回答by JJH

UISearchController's view has to be removed from its superview before deallocate. (guess it is a bug)

UISearchController 的视图必须在解除分配之前从其超视图中删除。(估计是bug)

Objective-C...

目标-C...

-(void)dealloc { 
    [searchController.view removeFromSuperview]; // It works!
}

Swift 3...

斯威夫特3...

deinit {
    self.searchController.view.removeFromSuperview()
}

I struggled with this issue for a couple of weeks. ^^

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

回答by MortalMan

Solved! It was a simple fix. I changed this code

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

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController = UISearchController()

to this:

对此:

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController: UISearchController!

This fixes the problem.

这解决了问题。

回答by nijm

Here is the Swift version that worked for me (similar toJJHs answer):

这是对我有用的 Swift 版本(类似于 JJH 的回答):

deinit{
    if let superView = resultSearchController.view.superview
    {
        superView.removeFromSuperview()
    }
}

回答by harsh_v

class SampleClass: UITableViewController, UISearchBarDelegate {

private let searchController =  UISearchController(searchResultsController: nil)

 override func viewDidLoad() {
        super.viewDidLoad()

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

}

回答by Derek

Hacking together a few solutions I managed to get mine working by adding lines to viewDidLoad beforefully setting up the UISearchController:

完全设置 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()

}

回答by Vincent

In Swift2 I got the same error message due to an obvious bug:

在 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)

Due to a stupid copy error from myself, I had not included the self.presentViewController line. This caused the same error.

由于我自己的一个愚蠢的复制错误,我没有包含 self.presentViewController 行。这导致了同样的错误。

回答by Milos Mandic

In Swift 2.2 version that worked for me

在对我有用的 Swift 2.2 版本中

deinit {
    self.searchController?.view.removeFromSuperview()
}

I think it's helpful!

我觉得很有帮助!

回答by Niels

Creating a search controller in viewDidLoad()and setting its search bar as the navigation item's title view doesn't create a strong reference to the search controller, which is why it's deallocated.

在其中创建搜索控制器viewDidLoad()并将其搜索栏设置为导航项的标题视图不会创建对搜索控制器的强引用,这就是它被释放的原因。

So instead of doing this:

所以不要这样做:

override func viewDidLoad() {
    super.viewDidLoad()
    // Create search controller
    let searchController = UISearchController(searchResultsController: nil)
    // Add search bar to navigation bar
    navigationItem.titleView = searchController.searchBar
    // Size search bar
    searchController.searchBar.sizeToFit()
}

You should do this:

你应该做这个:

var searchController: UISearchController!

override func viewDidLoad() {
    super.viewDidLoad()
    // Create search controller
    searchController = UISearchController(searchResultsController: nil)
    // Add search bar to navigation bar
    navigationItem.titleView = searchController.searchBar
    // Size search bar
    searchController.searchBar.sizeToFit()
}

回答by mehmetsen80

Mine is working like this

我的工作是这样的

func initSearchControl(){

        searchController = UISearchController(searchResultsController: nil)

        if #available(iOS 9.0, *) {
            searchController.loadViewIfNeeded()
        } else {
            let _ = self.searchController.view
        }

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        tableView.tableHeaderView = searchController.searchBar
        searchController.searchBar.sizeToFit()
    }

searchController.loadViewIfNeeded()solves the problem but you need to call it after initializing the searchController

searchController.loadViewIfNeeded()解决了问题但是需要在初始化searchController后调用

回答by Nikolai Ischuk

It's not a bug. It seems that you have to avoid creating ViewControllers without presenting them. So after SomeViewController()or let variable: SomeViewControlleryou have to call something like this self.presentViewController(yourViewController ...etc). If you don't do that, you will get this warning when this view controller will be dealocated.

这不是一个错误。似乎您必须避免在不呈现它们的情况下创建 ViewController。所以之后SomeViewController()orlet variable: SomeViewController你必须调用这样的东西self.presentViewController(yourViewController ...etc)。如果你不这样做,当这个视图控制器被解除分配时,你会收到这个警告。