UISearchController - Предупреждение Попытка загрузить представление контроллера вида

Я получаю следующую ошибку.

Попытка загрузить представление контроллера представления, пока он deallocating не допускается и может привести к undefined behavior()

Пробовал следующее решение, но не работает для меня Попытка загрузить представление контроллера представления при его освобождении... UISearchController

Демонстрационный проект доступен по ссылке.

  • Нажмите кнопку "Добавить" в главном контроллере, добавьте несколько штампов времени.
  • Переключение между строками контроллера основного вида и вы увидите вышеприведенную ошибку.

Код показан ниже и может быть загружен из краткого время в.

import UIKit

class DetailViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UISearchResultsUpdating,UISearchBarDelegate {

    @IBOutlet weak var basicTable: UITableView!        
    var tblSearchController:UISearchController!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.    
        self.tblSearchController = UISearchController(searchResultsController: nil)
        self.basicTable.tableHeaderView=self.tblSearchController.searchBar
//      self.tblSearchController.edgesForExtendedLayout = (UIRectEdge.Top )
//      self.tblSearchController.extendedLayoutIncludesOpaqueBars = true
        self.tblSearchController.searchResultsUpdater = self
        self.tblSearchController.searchBar.delegate = self
        self.tblSearchController.searchBar.sizeToFit()
//      self.tblSearchController.searchBar.frame=CGRectMake(0, 0, self.basicTable.frame.size.width, 44.0)
        self.tblSearchController.hidesNavigationBarDuringPresentation=true
        self.tblSearchController.dimsBackgroundDuringPresentation=true
        self.definesPresentationContext=true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 0
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let aCell:UITableViewCell! =  tableView.dequeueReusableCellWithIdentifier("123")
        return aCell
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        print("Begin Update = \(NSStringFromCGRect(self.tblSearchController.searchBar.frame)) \(self.tblSearchController.view.frame) ")
    }

    func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
        print("Begin= \(NSStringFromCGRect(searchBar.frame))")
    }

    func searchBarTextDidEndEditing(searchBar: UISearchBar) {
        print("End=\(NSStringFromCGRect(searchBar.frame))")
    }
}

Ответ 1

Проблема заключается в ошибке в UISearchController, где он пытается загрузить свое представление в свой метод dealloc. Вероятно, это называет self.view, и автор забыл, что self.view заставляет просмотр загружаться. Если UISearchController был создан, но не был использован, он не загружает свое представление, и эта проблема возникает. В вашем примере проекта, если вы нажмете в SearchBar, предупреждение не появляется.

Решение состоит в том, чтобы заставить его загрузить его представление. В вашем коде есть два места, которые вы можете сделать: viewDidLoad() или deinit. Используйте одну из предложенных строк (loadViewIfNeeded() или _ =.view) не для обоих. Если вы используете iOS 9, то лучше всего использовать код loadViewIfNeeded в deinit. Если вы поддерживаете iOS 8, загрузите представление вручную, как показано.

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.tblSearchController = UISearchController(searchResultsController: nil)
    // etc. setup tblSearchController       
    self.tblSearchController.loadViewIfNeeded()    // iOS 9
    let _ = self.tblSearchController.view          // iOS 8
}

deinit {
    self.tblSearchController.loadViewIfNeeded()    // iOS 9
    let _ = self.tblSearchController.view          // iOS 8
}

Ответ 2

Я вижу эту же проблему только для IOS9, а также отмечаю этот отчет об ошибке http://www.openradar.me/22250107. Похоже, в настоящее время решения нет.