在正确的地方调用 DispatchGroup()

Call DispatchGroup() in the right place

我想在遍历并将元素追加到数组后使用 DisaptchGroup 调用 func

这是 firebase 节点的样子

 {
       "tags": {
           "NewYork": {
                 uid1: 1
                 uid2: 1
           }, 
          "baseball": {
                 uid1: 1
           }
        }
    }

所以,基本上我所做的是在用户选择标签后,获取标签下的 uid 并将这些 uid 传递给数组。

func filterTempo(filterTag: FilteredTags) {

        let group = DispatchGroup()
        let tag = filterTag.selectedTag.components(separatedBy: "/") //it reutrns "NewYork" and "baseball"

            tag.forEach { (key) in
                self.ref.child("tags").child(key).observe(.value, with: { (snapshot) in
                    guard let dictionary = snapshot.value as? [String:Any] else { return }
                    for (key,_) in dictionary {
                        self.arrays.append(key)
                    }
           // want call func after iteration has finished.
                }, withCancel: nil)
            }
    }//func

第一次迭代后,数组会变成这样[uid1, uid2]。然后在第二次迭代后,数组将如下所示 [uid1, uid2, uid1]。我想在迭代完成后而不是中途调用函数( func fetchTeams(array: [String]) )。为了实现这一点,我尝试使用 DispatchGroup 但我在 func fetchTeams 中尝试了 print(array) 并且它 returns 就像这样。

[uid1, uid2]
[uid1, uid2, uid1]

我应该在哪里调用 DispatchGroup.enter()DispatchGroup.leave() 来解决这个问题? 提前致谢!

您每次都必须在调用observe之前调用group.enter()。在每个 observe 闭包中,工作完成后,调用 group.leave()。 一旦 enterleave 调用的数量抵消了(例如,所有输入的块都已保留),将调用 queue.notifiy 闭包,然后您可以在其中调用 fetchTerms 或其他东西否则:

func filterTempo(filterTag: FilteredTags) {

    let group = DispatchGroup()
    let tag = filterTag.selectedTag.components(separatedBy: "/") //it reutrns "NewYork" and "baseball"

        tag.forEach { (key) in
            group.enter()
            self.ref.child("tags").child(key).observe(.value, with: { (snapshot) in
                guard let dictionary = snapshot.value as? [String:Any] else { return }
                for (key,_) in dictionary {
                    self.arrays.append(key)
                }
                group.finished()
            }, withCancel: {
                // Maybe do some error handling here.
                group.finished()
            })
        }
        group.notify(queue: DispatchQueue.main)  {
            // called after all blocks have been finished.
            self.fetchTeams(self.arrays)
        }
}//func