【发布时间】:2021-06-10 20:42:21
【问题描述】:
我正在尝试在 for 循环中从 firebase 查询数据,我的问题是由于查询需要时间来连接,swift 正在跳过查询并稍后返回执行它们。这会产生问题,我的循环计数器正在增加,但查询被保存以备后用,当查询最终执行时,计数器变量完全不正常。
代码被跳过的地方是在查询之后,我试图追加到一个数组。
func getSelectedData() {
var exerciseIndex = 0
for i in 0...Master.exercises.count - 1 {
if Master.exercises[i].name == self.exerciseName {
exerciseIndex = i
}
}
let numOfSets = Master.exercises[exerciseIndex].totalSets
// For each date record
for count in 0...self.returnedExercises.count-1 {
// Creates a new dataSet
dataSet.append(dataSetStruct())
dataSet[count].date = returnedExercises[count]
for number in 0...(numOfSets - 1) {
// Retrives the reps
let repsDbCallHistory = db.collection("users").document("\(userId)").collection("ExerciseData").document("AllExercises").collection(exerciseName).document(returnedExercises[count]).collection("Set\(number + 1)").document("reps")
repsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].repsArray.append(data["Reps\(number + 1)"] as! Int)
}
else {
// error
}
}
//Retrives the weights
let weightsDbCallHistory = db.collection("users").document("\(userId)").collection("ExerciseData").document("AllExercises").collection(exerciseName).document(returnedExercises[count]).collection("Set\(number + 1)").document("weights")
weightsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].weightsArray.append(data["Weight\(number + 1)"] as! Float)
self.updateGraph()
}
else {
// error
}
}
}
}
}
我什至尝试将查询分解为另一个函数,但这似乎无法解决问题。
感谢您的帮助。
编辑:
func getSelectedData() {
if returnedExercises.count > 0 {
// Create a dispatch group
let group = DispatchGroup()
print("Getting Data")
// For each date record
for count in 0...self.returnedExercises.count-1 {
// Creates a new dataSet
self.dataSet.append(dataSetStruct())
self.dataSet[count].date = self.returnedExercises[count]
for number in 0...(self.numOfSets - 1) {
print("At record \(count), set \(number)")
// Enter the group
group.enter()
// Start the dispatch
DispatchQueue.global().async {
// Retrives the reps
let repsDbCallHistory = self.db.collection("users").document("\(self.userId)").collection("ExerciseData").document("AllExercises").collection(self.exerciseName).document(self.returnedExercises[count]).collection("Set\(number + 1)").document("reps")
repsDbCallHistory.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.dataSet[count].repsArray.append(data["Reps\(number + 1)"] as! Int)
print("Getting data: \(number)")
group.leave()
}
else {
// error
}
}
}
group.wait()
print("Finished getting data")
}
}
我现在尝试简化函数,并且函数中只有一个数据库调用来尝试调度组。我不确定为什么 firebase 会这样做,但代码从不执行 group.leave,程序只是闲置。如果我做错了什么,请告诉我,谢谢。
这是打印语句显示的内容:
获取数据
在记录 0 处,设置 0
在记录 0 处,设置 1
在记录 0 处,设置 2
在记录 1 处,设置 0
在记录 1 处,设置 1
在记录 1 处,设置 2
print("Getting data: (number)") 由于某种原因永远不会被执行。
我在想也许 firebase 调用是在单独的线程或其他东西上运行的,这也会使它们暂停执行,但这只是我的理论
EDIT2::
func getOneRepMax(completion: @escaping (_ message: String) -> Void) {
if returnedOneRepMax.count > 0 {
print("Getting Data")
// For each date record
for count in 0...self.returnedOneRepMax.count-1 {
// Creates a new dataSet
oneRPDataSet.append(oneRepMaxStruct())
oneRPDataSet[count].date = returnedOneRepMax[count]
// Retrives the reps
let oneRepMax = db.collection("users").document("\(userId)").collection("UserInputData").document("OneRepMax").collection(exerciseName).document(returnedOneRepMax[count])
oneRepMax.getDocument { (document, error) in
if let document = document, document.exists {
// For every document (Set) in the database, copy the values and add them to the array
let data:[String:Any] = document.data()!
self.oneRPDataSet[count].weight = Float(data["Weight"] as! String)!
print("Getting data: \(count)")
completion("DONE")
self.updateGraph()
}
else {
// error
}
}
}
}
}
我尝试将完成处理程序用于不同的功能,但它也无法正常工作。
self.getOneRepMax(completion: { message in
print(message)
})
print("Finished getting data")
打印语句的顺序:
获取数据
获取数据:0
完成
获取数据:1
完成
数据获取完毕
打印语句现在出来的顺序:
获取数据
完成获取数据
获取数据:1
完成
获取数据:0
完成
我什至不确定自从我的 for 循环计数后,计数怎么可能倒退,我犯了什么错误?
【问题讨论】:
-
请以文本形式发布您的代码,而不是屏幕截图(在手机上难以阅读且存在可访问性问题)
-
我按照建议更改了图像,但是链接似乎没有帮助,我尝试实现完成处理程序但同样的问题仍然发生@jnpdx
-
我建议您使用完成处理程序显示更新后的代码
-
嗨@jnpdx,我在尝试使用完成处理程序的地方添加了代码