在正确的位置调用DispatchGroup()

时间:2018-01-15 13:16:23

标签: arrays swift firebase-realtime-database dispatch dispatch-async

我想在迭代后使用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,但我在print(array)中尝试了func fetchTeams,它就像这样返回。

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

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

1 个答案:

答案 0 :(得分:1)

您必须在之前每次致电group.enter() 致电observe。在每个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