线程1:致命错误:在使用SearchController展开可选值时意外发现nil

时间:2018-11-19 03:20:50

标签: swift4

我一直在开发我自己的appCoda版本的应用程序。我在应用程序中以相同的方式输入搜索栏,但是在构建和运行应用程序时,在searchController.searchResultsUpdater = self处出现错误。当我注释掉相同的错误时,searchController.dimsBackgroundDuringPresentation = false。

导入UIKit 导入CoreData HousesTableViewController类:UITableViewController,NSFetchedResultsControllerDelegate,UISearchResultsUpdating {

var homes: [HomeMO] = []
var searchResults: [HomeMO] = []

var fetchResultController : NSFetchedResultsController<HomeMO>!
var searchController : UISearchController!


override func viewDidLoad() {
    super.viewDidLoad()

//错误在这里↓

    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false

    searchController = UISearchController(searchResultsController: nil)
    self.navigationItem.searchController = searchController


    navigationController?.navigationBar.tintColor = UIColor(red: 94, green: 252, blue: 161)
    if let customFont = UIFont(name: "Rubik-Medium", size: 40.0) {
        navigationController?.navigationBar.largeTitleTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: customFont ]
    }

    let fetchRequest: NSFetchRequest<HomeMO> = HomeMO.fetchRequest()
    let sortDescriptor = NSSortDescriptor(key: "price", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    if let appDelegate = (UIApplication.shared.delegate as? AppDelegate){
        let context = (appDelegate.persistentContainer.viewContext)
        fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        fetchResultController.delegate = self
        do{
            try fetchResultController.performFetch()
            if let fetchedObjects = fetchResultController.fetchedObjects{
                homes = fetchedObjects
            }
        } catch {
            print(error)
        }
    }




}





// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

    if searchController.isActive{
        return searchResults.count
    }else {

    return homes.count
    }
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "dataCell", for: indexPath) as! HomesTableViewCell


    let home = (searchController.isActive) ? searchResults[indexPath.row] : homes[indexPath.row]

    cell.priceLabel.text = "$" + home.price!

    if let homeImage = home.image{
        cell.thumbnailImageView.image = UIImage(data: homeImage as Data)
    }

    cell.amountOfBathsLabel.text = (home.amountOfBaths! + "ba")
    cell.amountOfBedsLabel.text = (home.amountOfBeds! + "bds")
    cell.locationLabel.text = home.location?.uppercased()
    cell.amountOfSquareFeetLabel.text = (home.amountOfSquareFeet! + "sqft")
    cell.typeLabel.text = home.type
    cell.layer.cornerRadius = 20
    cell.layer.masksToBounds = true

    // Configure the cell...

    return cell
}



func filterContent(for searchText: String) {
    searchResults = homes.filter({ (home) -> Bool in
        if let type = home.type {
            let isMatch = type.localizedCaseInsensitiveContains(searchText)
            return isMatch
        }
        return false
    })
}


func updateSearchResults(for searchController: UISearchController) {
    if let searchText = searchController.searchBar.text{
        filterContent(for: searchText)
        tableView.reloadData()
    }
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

    switch type {
    case .insert:
        if let newIndexPath = newIndexPath {
            tableView.insertRows(at: [newIndexPath], with: .fade)
        }
    case .delete:
        if let indexPath = indexPath {
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    case .update:
        if let indexPath = indexPath {
            tableView.reloadRows(at: [indexPath], with: .fade)
        }
    default:
        tableView.reloadData()
    }

    if let fetchedObjects = controller.fetchedObjects {
        homes = fetchedObjects as! [HomeMO]
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

@IBAction func unwindToHome(segue: UIStoryboardSegue){


    dismiss(animated: true, completion: nil)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showHomeDetail"{
        if let indexPath = tableView.indexPathForSelectedRow{
            let destinationController = segue.destination as! HomeDetailViewController
            destinationController.home = searchController.isActive ? searchResults[indexPath.row] : homes[indexPath.row]

        }

    }
}

}

1 个答案:

答案 0 :(得分:0)

查看您的代码。设置委托后, 会初始化控制器。始终在使用之前初始化对象。

所以改变顺序

searchController = UISearchController(searchResultsController: nil)    
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
self.navigationItem.searchController = searchController