This question has been asked before, but I am not able to get a clear explanation about this issue. I have a simple application with a tableview and a search function. In viewDidLoad()
, I call setUpSearchView()
which is defined like this
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = true
searchController.dimsBackgroundDuringPresentation = false
self.tableView.tableHeaderView = searchController.searchBar
This code doesn't not work properly. On the console, I can see this error
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior
Moreover, the searchcontroller does not animate properly and does not call updateSearchResultsForSearchController
delegate when I type on the searchbar.
But, all these issues are easily fixed by making a minor change to the searchController initialization function. Rather than declaring the searchController
as a local variable in the function, If I declare it an instance variable outside the method like this var searchController:UISearchController!
, everything works, although I have no idea why.
Now the code will look like this
var searchController:UISearchController!
In setUpSearchView()
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = true
searchController.dimsBackgroundDuringPresentation = false
self.tableView.tableHeaderView = searchController.searchBar
Here is a link to the viewController on github: https://github.com/tmsbn/marvel_heroes/blob/master/avengers/HeroesListController.swift
Can someone explain why this happens? Is this a bug with swift? Or it is something in iOS that I don't know about.
If you are creating a variable in a function (viewDidLoad) it's lifetime is the same as that functions lifetime. In this case you are trying to set the table header view as a searchController that is being deallocated (it's lifetime is the same as viewDidLoads)
When you create the variable outside of viewDidLoad and instantiate it later, the variable has the same lifespan as the viewController/class