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

Swift4 线程1:致命错误:在使用SearchController时展开可选值时意外发现nil,swift4,Swift4,我一直在用appCoda开发我自己的应用程序版本。我在应用程序中以相同的方式输入搜索栏,但当我构建并运行应用程序时,我在searchController.SearchResultsUpdate=self处收到一个错误。当我注释出相同的错误时,searchController.dimsBackgroundDuringPresentation=false 导入UIKit 导入CoreData 类HousesTableViewController:UITableViewController、NSFet

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

导入UIKit 导入CoreData 类HousesTableViewController:UITableViewController、NSFetchedResultsControllerDelegate、UISearchResultsUpdated{

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

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


override func viewDidLoad() {
    super.viewDidLoad()
var homes:[HomeMO]=[]
var searchResults:[HomeMO]=[]
var fetchResultController:NSFetchedResultsController!
var searchController:UISearchController!
重写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]

        }

    }
}
searchController.SearchResultsUpdate=self
searchController.dimsBackgroundDuringPresentation=false
searchController=UISearchController(searchResultsController:nil)
self.navigationItem.searchController=searchController
navigationController?.navigationBar.tintColor=UIColor(红色:94,绿色:252,蓝色:161)
如果让customFont=UIFont(名称:“Rubik中等”,大小:40.0){
navigationController?.navigationBar.largeTitleTextAttributes=[NSAttributedString.Key.foregroundColor:UIColor.white,NSAttributedString.Key.font:customFont]
}
let fetchRequest:NSFetchRequest=HomeMO.fetchRequest()
让sortDescriptor=NSSortDescriptor(键:“价格”,升序:true)
fetchRequest.sortDescriptors=[sortDescriptor]
如果让appDelegate=(UIApplication.shared.delegate为?appDelegate){
let context=(appDelegate.persistentContainer.viewContext)
fetchResultController=NSFetchedResultsController(fetchRequest:fetchRequest,managedObjectContext:context,sectionNameKeyPath:nil,cacheName:nil)
fetchResultController.delegate=self
做{
请尝试fetchResultController.performFetch()
如果让fetchedObjects=fetchResultController.fetchedObjects{
homes=fetchedObjects
}
}抓住{
打印(错误)
}
}
}
//标记:-表视图数据源
重写func numberOfSections(在tableView:UITableView中)->Int{
//#警告未完成执行,返回节数
返回1
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
//#警告未完成实现,返回行数
如果searchController.isActive{
返回searchResults.count
}否则{
返回家园
}
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
将cell=tableView.dequeueReusableCell(标识符为:“dataCell”,for:indexath)设为!HomesTableViewCell
let home=(searchController.isActive)?searchResults[indexPath.row]:homes[indexPath.row]
cell.pricellabel.text=“$”+home.price!
如果让homeImage=home.image{
cell.thumbnailImageView.image=UIImage(数据:homeImage作为数据)
}
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
//配置单元格。。。
返回单元
}
func filterContent(用于搜索文本:字符串){
searchResults=homes.filter({(home)->Bool-in
如果let type=home.type{
设isMatch=type.localizedCaseInsensitiveContains(搜索文本)
返回isMatch
}
返回错误
})
}
func updateSearchResults(对于searchController:UISearchController){
如果让searchText=searchController.searchBar.text{
filterContent(用于:searchText)
tableView.reloadData()
}
}
func tableView(tableView:UITableView,heightForHeaderInSection:Int)->CGFloat{
返回61.0
}
func controllerWillChangeContent(\ucontroller:NSFetchedResultsController){
tableView.beginUpdate()
}
func控制器(controller:NSFetchedResultsController,didChange anObject:Any,在indexPath:indexPath?处,对于类型:NSFetchedResultsChangeType,newIndexPath:indexPath?){
开关类型{
案例.插入:
如果让newindepath=newindepath{
tableView.insertRows(位于:[newIndexPath],带:.fade)
}
案例.删除:
如果让indexPath=indexPath{
tableView.deleteRows(位于:[indexPath],带:.fade)
}
案例。更新:
如果让indexPath=indexPath{
tableView.reloadRows(位于:[indepath],带:.fade)
}
违约:
tableView.reloadData()
}
如果让fetchedObjects=controller.fetchedObjects{
homes=获取对象为![HomeMO]
}
}
func controllerDidChangeContent(\控制器:NSFetchedResultsController){
tableView.endUpdates()
}
@iAction func unwindToHome(segue:UIStoryboardSegue){
驳回(动画:真,完成:无)
}
覆盖功能准备(对于segue:UIStoryboardSegue,发送方:有吗?){
如果segue.identifier==“showHomeDetail”{
如果让indexPath=tableView.indexPathForSelectedRow{
让destinationController=segue.destination为!HomeDetailViewController
destinationController.home=searchController.isActive?searchResults[indexPath.row]:homes[indexPath.row]
}
}
}

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

所以改变顺序

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