我正在使用 Dispatch Group 在我的字典中的所有值都被迭代后调用一个函数。在每个项目 block 的开头,我调用 enter()
然后调用leave()
在最后。我把调度组的notify
在每个项目的代码块末尾回调,但我想知道这是否真的会在每次项目完成时调用回调,而不是在所有项目完成后调用。这是我拥有的:
for value in snap {
self.dispatchGroup.enter()
let petName = value.key as! String
self.petsDict[petName] = UIImage()
// Check if pet's image is cached, otherwise fetch from db
if let petImg = petName.pngImageInDocumentsFolder() { // Image is cached
print("Image is cached \(petName)")
self.petsDict[petName] = petImg
self.dispatchGroup.leave()
} else { // Image not cached, fetch it
let imgRef = FIRStorage.storage().reference().child("profile_images").child(petName+".png")
imgRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if error != nil {
print(error?.localizedDescription ?? "")
self.dispatchGroup.leave()
} else if let data = data, let image = UIImage(data: data){
self.petsDict[petName] = image
self.dispatchGroup.leave()
}
}
}
self.dispatchGroup.notify(queue: DispatchQueue.main, execute: {
self.loadScrollView()
})
}
由于其中一些项目会同步执行(如果它们的图像被缓存),我认为下一个项目的循环甚至不会在调度组的 leave()
开始时开始。被称为,因此 notify
会被调用。
我是否应该单独放置一个 enter()
在这个 for 循环开始之前,然后是最后一个 leave()
在所有项目循环至少开始之后,以便他们的 enters()
是否入账?
编辑:我在我的回调函数中放置了一条打印语句,并确认它被调用了不止一次。我想我会采用上面的解决方案,除非有人有更好的解决方案。
最佳答案
在您的代码中,notify
位于循环内。它应该在 for-in
主体之后。
代码运行良好:
- 如果您有所有同步调用 - 立即通知调用 - 没关系,您的处理已结束
- 如果您有一些异步调用 - 通知会等到最后一个调用结束,就像您对每个循环项执行
enter
关于swift - 错误的 dispatch 组通知安置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42124449/