尝试加载视图控制器的视图,而它正在释放… UISearchController

我有UISearchController' in my UIVIew's viewDidLoad创build一个UISearchController' in my UIVIew's代码。

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

在此closures完成后,此警告将显示在控制台中:

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

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

UISearchController的视图必须在释放之前从其超级视图中移除。 (猜测这是一个错误)

Objective-C的…

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

Swift 3 …

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

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

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

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController = UISearchController() 

对此:

  class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController: UISearchController! 

这解决了这个问题。

这里是我工作的Swift版本(类似于JJHs的回答):

 deinit{ if let superView = resultSearchController.view.superview { superView.removeFromSuperview() } } 
 class SampleClass: UITableViewController, UISearchBarDelegate { private let searchController = UISearchController(searchResultsController: nil) override func viewDidLoad() { super.viewDidLoad() searchController.loadViewIfNeeded() // Add this line before accessing searchController } } 

在一起解决一些解决scheme之前,我设法完全设置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() } 

在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行。 这导致了相同的错误。

在Swift 2.2版本中为我工作

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

我认为这是有帮助的!

我的工作是这样的

 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之后调用它

viewDidLoad()创build一个search控制器,并将其search栏设置为导航项目的标题视图不会创build对search控制器的强引用,这就是为什么它被释放的原因。

所以不要这样做:

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

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

 var resultSearchController: UISearchController! 

)。 所以我之后就把它移动了,而且工作。

如果我完全拒绝了这个电话,这个错误依然存在,所以我相信这是答案的重要部分。 我无法在iOS 8上testing它。

这不是一个错误。 看来你必须避免创buildViewControllers而不显示它们。 所以在SomeViewController()let variable: SomeViewController你必须调用像这样self.presentViewController(yourViewController ...etc) 。 如果你不这样做,当这个视图控制器将被处理时,你会得到这个警告。

看起来这个视图是懒加载的,如果你分配了控制器而不显示它,视图就不会被加载。 在这种情况下,如果控制器被释放,您将收到此警告。 你可以显示一次,或者调用它的loadViewIfNeed()方法,或者使用'let _ = controller.view'来强制加载视图来避免这个警告。

我晚了一点,但这是我的解决scheme:

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

我希望这个对你有用。