致命错误:索引超出范围搜索项目

Posted

技术标签:

【中文标题】致命错误:索引超出范围搜索项目【英文标题】:fatal error: Index out of range search for an item 【发布时间】:2017-12-11 16:54:37 【问题描述】:

我有控制段和 UITableview。表会根据所选的段或执行的搜索重新加载。控制段工作正常,但搜索不工作。当我尝试在栏中输入任何内容时,它只会重新加载,当我单击单元格时它会崩溃。有人可以在这里帮助我吗?非常感谢你

   var auxiliar: [Shops]? = [Shops]()
   var searchActive: Bool = false    
// shops category
   var restuarnt = [Shops]()
   var coffee = [Shops]()
   var pharmacy = [Shops]()
   var supermarket = [Shops]()
   var home = [Shops]()
   var clothes = [Shops]()
   var allShops  = [Shops]()    
   var shops = [Shops]()

   var selectedIndex = 0



s.valueChange =  index in

            if index == 0 

                self.selectedIndex = 0
                self.tableView.reloadData()

            
            if index == 1 
                self.selectedIndex = 1

                self.tableView.reloadData()
            

            if index == 2 
                self.selectedIndex = 2

            
            if index == 3 

                self.selectedIndex = 3

            



func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if selectedIndex == 0 
            return  allShops.count

        
        if selectedIndex == 1 

            return self.coffee.count
        
        if selectedIndex == 2 

            return self.restuarnt.count
        
        if selectedIndex == 3 

            return self.pharmacy.count
        

        if searchActive 
            return auxiliar!.count
        else
            return   allShops.count

        

    


  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


    if selectedIndex == 0 

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell

        let entry = shops[indexPath.row]

        cell.shopImage.hnk_setImage(from: URL(string: entry.Logo))
        cell.shopName.text = entry.shopname
        cell.star.rating = Double(entry.rate)
        cell.time.text = entry.time


        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        return cell
    

    if selectedIndex ==  1 

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell

        let entry = coffee[indexPath.row]

        cell.shopImage.hnk_setImage(from: URL(string: entry.Logo))
        cell.shopName.text = entry.shopname
        cell.star.rating = Double(entry.rate)
        cell.time.text = entry.time


        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        return cell
    

    if selectedIndex ==  2 

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell

        let entry = restuarnt[indexPath.row]

        cell.shopImage.hnk_setImage(from: URL(string: entry.Logo))
        cell.shopName.text = entry.shopname
        cell.star.rating = Double(entry.rate)
        cell.time.text = entry.time


        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        return cell
    
    if selectedIndex ==  3 

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell

        let entry = pharmacy[indexPath.row]

        cell.shopImage.hnk_setImage(from: URL(string: entry.Logo))
        cell.shopName.text = entry.shopname
        cell.star.rating = Double(entry.rate)
        cell.time.text = entry.time


        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        return cell
    

    if searchActive

    
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell
        let entry1 = auxiliar?[indexPath.row]


        cell.shopImage.hnk_setImage(from: URL(string: (entry1?.Logo)!))
        cell.shopName.text = entry1?.shopname

        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        cell.time.text = entry1?.time

        cell.star.rating = Double((entry1?.rate)!)
        return cell
    
    else 


        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ShopTableViewCell

        let entry = shops[indexPath.row]

        cell.shopImage.hnk_setImage(from: URL(string: entry.Logo))
        cell.shopName.text = entry.shopname
        cell.star.rating = Double(entry.rate)
        cell.time.text = entry.time


        cell.backgroundColor = UIColor(white: 1 , alpha : 0.5)
        return cell

    




func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        tableView.deselectRow(at: indexPath, animated: true)
        if selectedIndex == 1 
            let meal1 =  coffee[indexPath.row]


            guard (coffee.count) > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = (meal1.familiy_id)
            viewController.name = (meal1.shopname)

            print("\(meal1.familiy_id) im the search ")
            view.animateRandom()
            self.present(viewController, animated: true , completion: nil)



        
        if selectedIndex == 0 
            let meal1 =  shops[indexPath.row]


            guard (shops.count) > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = (meal1.familiy_id)
            viewController.name = (meal1.shopname)

            print("\(meal1.familiy_id) im the search ")
            view.animateRandom()
            self.present(viewController, animated: true , completion: nil)



        
        if selectedIndex == 2 
            let meal1 =  restuarnt[indexPath.row]


            guard (restuarnt.count) > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = (meal1.familiy_id)
            viewController.name = (meal1.shopname)

            print("\(meal1.familiy_id) im the search ")
            view.animateRandom()
            self.present(viewController, animated: true , completion: nil)



        
        if selectedIndex == 3 
            let meal1 =  pharmacy[indexPath.row]


            guard (pharmacy.count) > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = (meal1.familiy_id)
            viewController.name = (meal1.shopname)

            print("\(meal1.familiy_id) im the search ")
            view.animateRandom()
            self.present(viewController, animated: true , completion: nil)



        

        if searchActive 
            let meal1 =  auxiliar?[indexPath.row]


            guard (auxiliar?.count)! > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = (meal1?.familiy_id)!
            viewController.name = (meal1?.shopname)!

            print("\(meal1?.familiy_id) im the search ")
          view.animateRandom()
            self.present(viewController, animated: true , completion: nil)




         else 
            let meal =  shops[indexPath.row]


            guard shops.count > indexPath.row else 
                print("Index out of range")
                return
            

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! MealsDetailsController
            viewController.passedValue = meal.familiy_id
            viewController.name = meal.shopname
            view.animateRandom()
            self.present(viewController, animated: true , completion: nil)


        

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
        auxiliar = shops.filter  $0.shopname.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        if searchText == "" || searchBar.text == nil 
            auxiliar = shops
        
        tableView.reloadData()
    

崩溃是由这一行引起的let meal1 = auxiliar?[indexPath.row]

【问题讨论】:

哪行代码抛出错误?请提供Minimal, Complete and Verifiable example。不相关,但不是没有else 分支的单独的if 子句,您应该使用switch 语句来使您的代码更具可读性。 let meal1 = auxiliar?[indexPath.row] 【参考方案1】:

你应该交换以下两个语句:

let meal1 = auxiliar?[indexPath.row]
guard (auxiliar?.count)! > indexPath.row else 
    print("Index out of range")
    return

尝试下标是没有意义的(如果auxiliar.count <= indexPath.row 会导致异常),然后检查下标是否真的安全。

应该是:

guard auxiliar.count > indexPath.row else 
    print("Index out of range")
    return

let meal1 = auxiliar[indexPath.row]

此外,var auxiliar: [Shops]? = [Shops]() 毫无意义。如果您为auxiliar 提供默认值,为什么要将其定义为Optional?只需简单地将auxiliar 声明为var auxiliar = [Shops]() 的非可选。

此外,您应该重新访问您的 tableView(:numberOfRowsInSection:) 实现,因为您正在检查两个不同的变量以确定要返回的值,如果您不重置 selectedIndex,这很容易导致问题,因为在这种情况下,函数永远无法到达if searchActive 部分。

您还应该重构代码并使用 switch 语句,而不是多个具有不同条件且没有 else 分支的 if 语句。

【讨论】:

感谢您的回答!我确实修复了它,它现在没有崩溃,但搜索结果不正确 我在我的问题中添加了textDidChange,请查看我是如何编码的

以上是关于致命错误:索引超出范围搜索项目的主要内容,如果未能解决你的问题,请参考以下文章

在 ForEach 循环中删除项目会导致致命错误:索引超出范围

Swift 致命错误:数组索引超出范围

Swift TableView ImageView + Label = 致命错误:索引超出范围

Swift,CollectionView,致命错误:索引超出范围

致命错误:索引超出范围,同时在 SwiftUI 的列表中从 Firebase 中删除项目

致命错误:注册后索引超出范围(Firebase、Swift)