这是我初始化字符串数组的地方:
let databaseRef = FIRDatabase.database().reference().child("Butikker")
self.shopItems = [String]()
databaseRef.observe(FIRDataEventType.value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! FIRDataSnapshot
let dictionary = snap.value as! [String: AnyObject]
self.shopItems.append(dictionary["Name"] as! String)
}
})
这是我的 tableview :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as UITableViewCell
let when = DispatchTime.now() + 5
DispatchQueue.main.asyncAfter(deadline: when) {
print(self.shopItems[indexPath.row])
cell.textLabel?.text = self.shopItems[0]
}
return cell
}
我的问题是,当我尝试打印shopItem[index.row]
时,为什么我的应用会崩溃?我将如何解决此问题?
答案 0 :(得分:1)
我不确定这是否能解决您的问题,但我对您的代码进行了一些基本的改进,可能会阻止您的应用程序崩溃。
1:从Firebase获取快照后,我总是会检查它是否确实存在;你可以通过调用if !snapshot.exists() { return }
和for-in-loop if !child.exists() { return }
来做到这一点。在return语句之前,如果您愿意,可以实现错误处理。这意味着如果由于任何原因没有可检索的快照,它将阻止代码运行。
2:我总是使用if-let-statement获取快照值。这也可能是你问题的一部分。只需致电:
if let dictionary = snap.value as? [String:AnyObject] {
// do whatever you want to do if the dictionary can be created
} else { print("For some reason couldn't initialize the dictionary.")}
这也可以防止您的应用崩溃(以防万一)并且可以告诉您它是否无法找到您需要的值。
3:不要依赖于执行cellForRowAtIndexPath()方法中的代码 - 异步并延迟执行。如果您的互联网连接不良,则该应用程序不太可能需要更多时间加载并且数据不会出现。相反,在代码的第一部分中使用for-in-loop调用此方法:tableView.reloadData() // replace tableView with whatever your tableView is called
。这意味着,每当有新值时,它就会自动重新加载数据,这样您就不必担心在途中丢失数据。
实际上解决了你所问的问题:很明显,indexPath.row的索引超出了范围,我想我知道原因:在numberOfRowsInSection方法中你是否有可能这样做?或者根本不调用shopItems.count
或者不是异步调用?
如果没有,您可以通过调用cellForRowAtIndexPath() - 方法
print("Number of shops items: \(shopItems.count); Current index path. \(indexPath.row)")
这至少会为您提供解决问题的所有重要价值。希望我能提供帮助。