从Firestore数据库导入数据时遇到问题。
基本上,我使用的是值index
,该值是从以前的View Controller中的表视图作为indexPath?.row
继承的。当在阵列中使用index
时出现致命错误,错误为fatal error: Index out of range
。
以下代码来自此新的重定向View Controller:
import Firebase
class DetailedSubjectsViewController: UIViewController {
var index: Int!
var database: Firestore!
var subjectsArray = [Subjects]()
override func viewDidLoad() {
super.viewDidLoad()
database = Firestore.firestore()
loadData()
let subjects = subjectsArray[index] // fatal error: Index out of range
labelTitle.text = subjects.name
}
func loadData() {
let uid = Auth.auth().currentUser?.uid
database.collection("users").document(uid ?? "").collection("subjects").getDocuments { (querySnapshot, error) in
if let error = error {
fatalError("Fatal error: \(error.localizedDescription)")
} else {
self.subjectsArray = querySnapshot!.documents.compactMap({ Subjects(dictionary: $0.data())})
}
}
}
}
这是上一个View Controller中的代码:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = tableviewSubjects.indexPathForSelectedRow
let indexNumber = indexPath?.row
let detailedSubjectsViewController = segue.destination as! DetailedSubjectsViewController
detailedSubjectsViewController.index = indexNumber
}
有什么办法可以解决此问题?感谢所有帮助!
答案 0 :(得分:1)
您被困在异步陷阱中。添加完成处理程序。
import Firebase
class DetailedSubjectsViewController: UIViewController {
var index: Int!
var database: Firestore!
var subjectsArray = [Subjects]()
override func viewDidLoad() {
super.viewDidLoad()
database = Firestore.firestore()
loadData() { [weak self] result in
switch result {
case .success(let data):
DispatchQueue.main.async {
self?.subjectsArray = data
if self?.index < data.count {
let subject = data[index]
self?.labelTitle.text = subject.name
}
}
case .failure(let error):
fatalError("Fatal error: \(error.localizedDescription)")
}
}
}
func loadData(completion: @escaping (Result<[Subjects],Error>)->Void) {
let uid = Auth.auth().currentUser?.uid
database.collection("users").document(uid ?? "").collection("subjects").getDocuments { (querySnapshot, error) in
if let error = error {
completion(.failure(error))
} else {
let subjects = querySnapshot!.documents.compactMap({ Subjects(dictionary: $0.data())})
completion(.success(subjects))
}
}
}
}
答案 1 :(得分:0)
对于其中一个,您可以添加防护装置以防发生此问题:
database = Firestore.firestore()
loadData()
guard index < subjectsArray.count else { return }
...
接下来,请注意您的loadData()正在执行数据的异步加载,这就是为什么您有一个在数据完全加载后被调用的回调方法的原因。
在回调之前,subjectArray可能为空(并且是!),因此存在越界问题。
// let subjects = subjectsArray[index] // fatal error: Index out of range
// labelTitle.text = subjects.name
}
func setSubjectTitle() {
guard index < subjectsArray.count else { return }
let subject = subjectsArray[index]
labelTitle.text = subject.name
}
func loadData() {
let uid = Auth.auth().currentUser?.uid
database
.collection("users").document(uid ?? "")
.collection("subjects").getDocuments { (querySnapshot, error) in
if let error = error {
fatalError("Fatal error: \(error.localizedDescription)")
} else {
self.subjectsArray = querySnapshot!.documents.compactMap({ Subjects(dictionary: $0.data())})
}
self.setSubjectTitle()
}
}
}