ディスパッチグループを使用して、辞書内のすべての値が繰り返し処理されたら関数を呼び出しています。各項目のブロックの開始時に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
が呼び出されます。
forループの開始前に別のenter()
を置くべきですか?enters()
がすべてのアイテムループが開始された後で、最後のleave()
が最後に処理されましたか?
編集:私はコールバック関数にprintステートメントを置き、複数回呼び出されていることを確認しました。私は誰かがより良いものを持っていない限り、私は上記の私のソリューションと一緒に行くだろうと思う。