【问题标题】:observeSingleEvent is not called under swift loop在快速循环下不调用observeSingleEvent
【发布时间】:2019-10-09 15:32:17
【问题描述】:

我试图在 swift 循环下调用“observeSingleEvent”,但它在本地循环完成后被调用

func fetchAllComments(){

    let myGroup = DispatchGroup()
    DispatchQueue.main.async {
        myGroup.enter()
        for index in self.spotVideos {
            var id = String(index.videoId)
            print(id)
            var count = 0
            self.videoRef = rootRef.child(id)
                self.videoRef!.observeSingleEvent(of: .value) { snapshot in
                    print(snapshot.childrenCount)
                    myGroup.leave()
                }
            myGroup.wait()
        }

        myGroup.notify(queue: .main) {
            print("Finished all requests.")
        }
    }
}

【问题讨论】:

  • 您将异步 firebase 调用放入异步调度队列中,并在 firebase 一遍又一遍地返回数据时离开组。你能澄清一下你想在那里做什么吗?此外,通常不鼓励将 firebase 调用放在一个紧密的循环中——它也可以帮助我们理解你的 Firebase 结构——你能把它包括进去吗?要获取您的 Firebase 结构,请使用 Firebase 控制台->导出 JSON,然后复制并粘贴您的结构的 sn-p。见images and links are evil
  • 在每个 id 上,我试图检查有多少孩子
  • 还有一点不清楚为什么 `self.videoRef' 是一个类 var - 它在这个循环中被一遍又一遍地替换,所以可能应该只是一个本地函数 var。

标签: swift firebase firebase-realtime-database grand-central-dispatch


【解决方案1】:

您应该在循环之后使用 myGroup.enter()。进入的次数取决于离开的次数。如果您的循环运行 3 次,则应该有 3 次进入和 3 次离开,在您的情况下,您有 1 次进入,所以当它获得一次离开时,它会通知。

  for index in self.spotVideos {
     myGroup.enter()
...
}

【讨论】:

  • 他们还需要删除myGroup.wait()。这也可以删除DispatchQueue.main.async {,因为它是redudent,因为您已经创建了一个调度组myGroup
  • 还是同样的问题
【解决方案2】:

让我们尝试一种更简单的方法。

这是要让球滚动的函数。请注意,一旦计算了孩子,就有一个完成闭包来处理需要完成的任何事情。

func startFetch() {
    self.fetchAllComments {
        print("done!")
    }
}

然后是遍历spotVideos 并获取其ID 的函数。打印每个节点的子节点数,完成后返回。

func fetchAllComments(completion: @escaping () -> Void) {
    let lastIndex = self.spotVideos.count - 1
    for (index, vidId) in self.spotVideos.enumerated() {
        let ref = rootRef.child(vidId)
        ref.observeSingleEvent(of: .value, with: { snapshot in
            print("vid id: \(vidId) has \(snapshot.childrenCount) children")
            if index == lastIndex {
                completion()
            }
        })
    }
}

【讨论】:

  • 所以当外循环完成后firebase调用返回
  • @taimoor 该函数遍历所有 vidId 节点,然后当 last 完成读取时,调用完成处理程序。
猜你喜欢
  • 2016-10-14
  • 1970-01-01
  • 2015-04-11
  • 2020-02-17
  • 2017-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多