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

时间:2015-08-29 03:23:30

标签: ios swift uisearchcontroller

我有创建UISearchController' in my UIVIew's viewDidLoad`的代码。

 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

    })()

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

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

我不知道我做错了什么。 This similar question并非我的情况(至少我不这么认为)。发生了什么事?

12 个答案:

答案 0 :(得分:36)

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

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController = UISearchController()

到此:

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController: UISearchController!

这解决了这个问题。

答案 1 :(得分:20)

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

HashSet

答案 2 :(得分:11)

class SampleClass: UITableViewController, UISearchBarDelegate {

private let searchController =  UISearchController(searchResultsController: nil)

 override func viewDidLoad() {
        super.viewDidLoad()

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

}

答案 3 :(得分:10)

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

double u = 0.5 - atan2(n.z, n.x) * math::one_over_2pi;
double v = 0.5 - asin(n.y) * math::one_over_pi;

答案 4 :(得分: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)

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

答案 5 :(得分:7)

在适合我的Swift 2.2版本中

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

我觉得它很有用!

答案 6 :(得分:2)

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

所以不要这样做:

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()
}

你应该这样做:

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()
}

答案 7 :(得分:2)

我这样工作

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()解决了问题但你需要在初始化searchController后调用它

答案 8 :(得分:1)

我使用了Derek的答案,但不得不稍微改变一下。 提供的答案对我来说是崩溃的,因为对loadViewIfNeeded()的调用发生在定义resultSearchController之前。 (我的声明是

var resultSearchController: UISearchController!

)。所以我之后就把它移了,它起作用了。

如果我完全省略了电话,那么错误仍然存​​在,所以我确信这是答案的重要部分。我无法在iOS 8上测试它。

答案 9 :(得分:1)

这不是一个错误。看来你必须避免创建ViewControllers而不显示它们。因此,在SomeViewController()let variable: SomeViewController之后,您必须调用此类self.presentViewController(yourViewController ...etc)之类的内容。如果不这样做,当这个视图控制器被处理时,你会收到此警告。

答案 10 :(得分:1)

看起来视图是延迟加载的,如果你分配了控制器并且从不显示它,则不加载视图。在这种情况下,如果取消分配控制器,您将收到此警告。你可以展示一次,或称之为loadViewIfNeed()方法,或者使用&#39; let _ = controller.view&#39;强制加载视图以避免此警告。

答案 11 :(得分:0)

我参加派对有点晚了,但这是我的解决方案:

var resultSearchController: UISearchController!

override func viewDidLoad()
{
    super.viewDidLoad()

    self.resultSearchController = ({
        let searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.sizeToFit()
        return searchController
    })()

    self.tableView.tableHeaderView = self.resultSearchController.searchBar
    self.tableView.reloadData()
}

我希望它适合你。