Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在获取数据期间,节中的行数索引超出范围_Ios_Swift_Xcode_Firebase - Fatal编程技术网

Ios 在获取数据期间,节中的行数索引超出范围

Ios 在获取数据期间,节中的行数索引超出范围,ios,swift,xcode,firebase,Ios,Swift,Xcode,Firebase,当尝试用我的tableview和进度条打开新控制器时,我的“索引超出范围”。 我从Firestore数据库获取数据,其想法是,当我点击“下一步”按钮时,我想更新进度条,并用新值重新加载表视图。行数必须等于集合数,但每个练习的集合数不同,因此我希望动态更改行数 class StartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var titleValue: String = &q

当尝试用我的tableview和进度条打开新控制器时,我的“索引超出范围”。 我从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!
  }

您是基于行数的
models[exerciseNumber]。集合

您正在设置中的练习编号

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

有一些更聪明的方法可以做到这一点,但这一点目前仍然有效。

您是基于行数计算的
models[exerciseNumber]。集合

您正在设置中的练习编号

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

有更聪明的方法可以做到这一点,但这一点目前仍然有效。

您有一个时间问题。视图将在加载时尝试创建tableView。此时,模型数组将为空,因为异步firebase方法不会运行和更新它。但您将exerciseNumber初始化为0

这意味着
numberOfRowsInSection
delegate方法将尝试访问
模型[0
],但由于此时数组为空,因此不存在,并导致索引超出范围崩溃

您可以通过一些防御性编程来解决此问题:

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
      guard !model.isEmpty else {return 0}
      return models[exerciseNumber].sets!
  }

您还可以添加第二个保护或先决条件,以确保exerciseNumber您有一个时间问题。视图将在加载时尝试创建tableView。此时,模型数组将为空,因为异步firebase方法不会运行和更新它。但您将exerciseNumber初始化为0

这意味着
numberOfRowsInSection
delegate方法将尝试访问
模型[0
],但由于此时数组为空,因此不存在,并导致索引超出范围崩溃

您可以通过一些防御性编程来解决此问题:

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
      guard !model.isEmpty else {return 0}
      return models[exerciseNumber].sets!
  }

您还可以添加第二个保护或先决条件,以确保exerciseNumber尝试在
retrieveWorkouts
方法内的主线程上调用
重新加载数据。您确定nextExercise中的逻辑吗?我认为您在它里面切换了if和else条件。不幸的是,在主线程中重新加载数据不起作用,尽管如此,您还是应该这样做。你确定下一步的方法吗?是的,我确定。唯一不起作用的是在section函数中将集合数检索为行数。这有点离题,但您不会希望在snapshotDocuments中的文档的for循环
中反复重新加载tableView。在此之后移动重新加载,以便在填充数据源后只需执行一次。尝试在
retrieveWorkouts
方法内的主线程上调用
reloadData
。您确定nextExercise中的逻辑吗?我认为您在它里面切换了if和else条件。不幸的是,在主线程中重新加载数据不起作用,尽管如此,您还是应该这样做。你确定下一步的方法吗?是的,我确定。唯一不起作用的是在section函数中将集合数检索为行数。这有点离题,但您不会希望在snapshotDocuments中的文档的for循环
中反复重新加载tableView。在此之后移动重新加载,以便在填充数据源后只需执行一次。不幸的是,它仍然无法工作。但是我怀疑我在nextExercise中的逻辑是否错误,因为我从exerciseNumber=0开始,如果exerciseNumber大于models.count我递增,但当exerciseNumber等于models.count时,我的exerciseNumber将再次为0,因此我将从头开始,这里出了什么问题?我道歉-我把它误读为
如果练习
。在阅读、剪切和粘贴时,我设法错过了
+1
位。我的错!不幸的是,它仍然不起作用。但是我怀疑我在nextExercise中的逻辑是否错误,因为我从exerciseNumber=0开始,如果exerciseNumber大于models.count我递增,但当exerciseNumber等于models.count时,我的exerciseNumber将再次为0,因此我将从头开始,这里出了什么问题?我道歉-我把它误读为
如果练习
。在阅读、剪切和粘贴时,我设法错过了
+1
位。我的错!谢谢你,伙计,真管用!谢谢你,伙计,真管用!