我正在尝试从我的Firebase数据库检查是否存在某些节点,如果没有,请在数据库中创建新节点。我需要我的方法loadAll()
才能在调用第二个创建任何缺失节点autoCheck
的方法之前完全执行。我尝试了一个调度组来执行此操作,但它不起作用,在检查数据库之前调用print("Done downloading!")
。谢谢!
代码:
func loadAll(){
var deleted_load = false
var poor_load = false
var allLoadDone = false
if let user = FIRAuth.auth()?.currentUser {
let uid = user.uid
let refff = FIRDatabase.database().reference()
let userRef = refff.childByAppendingPath("users/\(uid)")
//When making new fields increase this var
var howmany = 2
var done = 0
var downloadGroup = dispatch_group_create()
dispatch_group_enter(downloadGroup)
userRef.queryOrderedByValue().observeEventType(.ChildAdded, withBlock: { snapshot in
allLoadDone = true
if(!snapshot.exists()){
print("ERR DOES NOT EXCIST")
self.autoCheck(deleted_load, poor_load: poor_load, userRef: userRef, ig: 1)
return
}
if let score = snapshot.value as? Int {
if(snapshot.key=="deleted"){
deleted_load = true
}
if(snapshot.key=="Staff_Poor"){
poor_load = true
}
print("\(snapshot.key) is \(score)")
self.counter.text = String(score)
}
done = done + 1
if(done>=(howmany)){
self.autoCheck(deleted_load, poor_load: poor_load, userRef: userRef, ig: 2)
}
})
dispatch_group_leave(downloadGroup)
dispatch_group_notify(downloadGroup, dispatch_get_main_queue()) { // 2
print("Done downloading!")
}
} else {
print("No user!")
gotoLogin()
}
}
func autoCheck(deleted_load: Bool, poor_load: Bool, userRef: FIRDatabaseReference, ig: Int) -> Bool{
print("ID IS: \(ig)")
var newUserData = ["deleted": 0, "Staff_Poor": 0]
print("deleted_load: \(deleted_load)")
if deleted_load==true{
newUserData.removeValueForKey("deleted")
}
print("poor_load: \(poor_load)")
if poor_load==true{
newUserData.removeValueForKey("Staff_Poor")
}
if(!newUserData.isEmpty){
userRef.updateChildValues(newUserData)
}
return true
}
答案 0 :(得分:3)
您对dispatch_group_leave(downloadGroup)
的调用必须放在完成处理程序关闭内。现在,你把它放在外面,这意味着该组将在异步调用完成之前完成。
但让我们退后一步,了解调度组的目的。典型的模式是在您执行一系列异步任务时使用调度组,并且您想知道他们何时完成所有操作。因此,对于每个任务,在调用某个异步进程之前进入该组,然后将该组保留在该异步进程的完成处理程序中,如:
let group = dispatch_group_create()
for object in arrayOfObjects {
dispatch_group_enter(group)
performSomeAsynchronousActionWithObject(object) { result in
// do something with `result`
...
dispatch_group_leave(group)
}
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
print("done performing asynchronous task with all of those objects")
}
坦率地说,在这里使用调度组可能不合适。调度组的概念是每个"进入"匹配相应的"离开"。你正在打电话"输入"曾经,但不清楚你有什么保证观察者最终会被召唤多少次。
但是在这种情况下,你正在处理一个"观察者",一些将被调用的代码块,但事件发生的次数很多。它可能根本不会发生。它可能会发生很多次。这只是观察事件发生次数的问题。
现在,如果你肯定知道这只会被调用一次,那么从技术上讲这种模式就可以了。但是,如果它只被召唤一次,那么你根本不需要一个派遣小组。