首页 > 解决方案 > 在获取数据期间索引超出部分中的行数范围

问题描述

何时尝试使用我的表格视图和进度条打开新控制器时出现“索引超出范围”。我从 Firestore 数据库中获取数据,想法是当我点击“下一步”按钮时,我想更新进度条并使用新值重新加载表视图。行数必须等于组数,但每个练习都有不同的组数,所以我想动态更改行数。

class StartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

  var titleValue: String = ""
  var dayOfWorkout: String = ""
  var exerciseNumber = 0

  var models: [DataCell2] = []
  let user = Auth.auth().currentUser
  var db = Firestore.firestore()
    
  @IBOutlet weak var tableView: UITableView!
  @IBOutlet weak var exerciseLabel: UILabel!
  @IBOutlet weak var progressView: UIProgressView!


  override func viewDidLoad() {
     super.viewDidLoad()
       
     progressView.transform = progressView.transform.scaledBy(x: 1, y: 3)   
     tableView.delegate = self
     tableView.dataSource = self
     retrieveWorkouts()
  }
    
  @IBAction func nextButtonPressed(_ sender: UIButton) {
        
     nextExercise()
        
     Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
     tableView.reloadData()
  }
    
  @objc func updateUI() {
     progressView.progress = getProgress() 
  }
    
  func getProgress() -> Float {
     return Float(exerciseNumber) / Float(models.count)
  }
    
  func nextExercise() {
        
     if exerciseNumber + 1 < models.count {
        exerciseNumber += 1
     } else {
        exerciseNumber = 0
     }
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
      **//HERE IS ERROR**  
      return models[exerciseNumber].sets!
  }

以及从 Firestore 获取数据的方法

func retrieveWorkouts() {

   db.collection("users").document("\(user!.uid)").collection("WorkoutsName").document("\(titleValue)").collection("Exercises").order(by: "Number").getDocuments { (querySnapshot, error) in
      if let error = error{
         print("\(error.localizedDescription)")
      }else {
         if let snapshotDocuments = querySnapshot?.documents {
            for doc in snapshotDocuments {
                let data = doc.data()
                if let numberDb = data["Number"] as? Int, let exerciseDb = data["Exercise"] as? String, let kgDb = data["kg"] as? Int, let setsDb = data["Sets"] as? Int, let repsDb = data["Reps"] as? Int, let workoutName = data["workoutName"] as? String {
                    print("data is \(data)")
                    let newModel = DataCell2(Number: numberDb, Exercise: exerciseDb, kg: kgDb, sets: setsDb, reps: repsDb, workoutName: workoutName)
                    self.models.append(newModel)
                    self.tableView.reloadData()
                }                   
             }
          }
       }
    }
 }

标签: iosswiftxcodefirebase

解决方案


您基于的行数 models[exerciseNumber].sets!

并且您正在将锻炼次数设置为

func nextExercise() {
        
     if exerciseNumber + 1 < models.count {
        exerciseNumber += 1
     } else {
        exerciseNumber = 0
     }
  }

但是,您在这里有一个逻辑错误:您正在检查练习数是否小于 models.count,如果是,则增加它。这将导致exerciseNumber == models.count,并且由于数组是零索引的,这将超出数组的末尾并给出超出范围的错误。

一个简单的解决方法是将方法更改为:

func nextExercise() {
   exerciseNumber += 1
   if exerciseNumber == models.count {
      exerciseNumber = 0
   }
   return exerciseNumber
}

有更聪明的方法可以做到这一点,但现在这将起作用。


推荐阅读