1

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

答えて

2

コードには、notifyがループ内にあります。体はfor-inの後にする必要があります。

コードが正常に動作します:あなたはすべての同期呼び出しを持っている場合

  • - すぐに呼び出しを通知 - それは大丈夫です、あなたの処理はあなたには、いくつかの非同期呼び出しを持っている場合
  • 終了している - の終わりまで待機を通知あなたがやるように最後の1つは、ループの項目ごとにenter
関連する問題