Разница между до и после в viewDidLoad

Я попытался установить searchBar как tableHeaderView внутри viewDidLoad:

 override func viewDidLoad() {
    super.viewDidLoad()


    // SearchController initializiation
    self.searchController = UISearchController.init(searchResultsController: nil)
    self.searchController.delegate = self
    self.searchController.searchBar.delegate = self
    self.searchController.searchBar.sizeToFit()
    self.searchController.searchResultsUpdater = self
    self.searchController.searchBar.barTintColor = UIColor.white
    self.searchController.searchBar.keyboardAppearance = .default
    self.searchController.searchBar.backgroundColor = UIColor.white
    self.searchController.hidesNavigationBarDuringPresentation = true
    self.searchController.obscuresBackgroundDuringPresentation = false


    self.tableView.tableHeaderView = self.searchController.searchBar
    self.definesPresentationContext = true

    self.fetch()
    self.tableView.reloadData()

}

И эта моя функция fetch():

func fetch() {
    let fetchRequest:NSFetchRequest<Phone> = Phone.fetchRequest()
    fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "header", ascending: true), NSSortDescriptor.init(key: "date", ascending: true)]

    self.fetchedResultsController = NSFetchedResultsController.init(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: "header", cacheName: nil)
    self.fetchedResultsController.delegate = self

    do {
        try self.fetchedResultsController.performFetch()
        self.tableView.reloadData()
    } catch {}

}

Но я не понимаю, что они не работают. Ошибка Xcode и ничего не происходит. И затем я попытался что-то изменить внутри метода viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    self.fetch()
    self.tableView.reloadData()

    // SearchController initializiation
    self.searchController = UISearchController.init(searchResultsController: nil)
    self.searchController.delegate = self
    self.searchController.searchBar.delegate = self
    self.searchController.searchBar.sizeToFit()
    self.searchController.searchResultsUpdater = self
    self.searchController.searchBar.barTintColor = UIColor.white
    self.searchController.searchBar.keyboardAppearance = .default
    self.searchController.searchBar.backgroundColor = UIColor.white
    self.searchController.hidesNavigationBarDuringPresentation = true
    self.searchController.obscuresBackgroundDuringPresentation = false


    self.tableView.tableHeaderView = self.searchController.searchBar
    self.definesPresentationContext = true



}

Успех! Работает должным образом. Я не понимаю, в чем разница?

Ответ 1

Вы должны попробовать удалить self.tableView.reloadData() из метода viewDidLoad(), потому что данные не были загружены даже для перезагрузки.

Ответ 2

Это связано с тем, что вы устанавливаете делегаты для поискаResultsUpdater и searchBar, прежде чем инициализируется даже ваш fetchedResultsController. Некоторые, где в вашем коде searchResultsUpdater или searchBar делегируют методы, получают доступ к вашему fetchedResultsController и получают его нуль, чтобы приложение зависало. Мое предложение состоит в том, чтобы избежать краха, чтобы сделать searchResultsController как вычисленное или ленивое свойство.