前提・実現したいこと
For文の中の非同期処理でリストを作成し、For文の外でリストを活用したいと考えています。
しかし、非同期処理なので、For文の中の処理を待たずに、リストが空の状態で処理が進みます。
調べていて、DispatchSemaphoreを活用することは分かったのですが、どうも上手くいきません。
使い方が間違っていると思うのですが、調べても原因が分からず困っています。
発生している問題・エラーメッセージ
処理が進まなくなった。
該当のソースコード
Swift
1let semaphore = DispatchSemaphore(value: 0) 2var testList = [String: Test]() 3 4for value in list { 5 //非同期処理スタート 6 db.collection("Test").document(value) 7 .getDocument { (document, error) in 8 9 if let error = error { 10 print("Error getting documents: (error)") 11 } else { 12 let result = Result { 13 try document?.data(as: Test.self) 14 } 15 switch result { 16 case .success(let resultValue): 17 if let test = resultValue { 18 testList[document!.documentID] = test 19 } else { 20 print("Document does not exist") 21 } 22 case .failure(let error): 23 print("Error decoding city: (cError)") 24 } 25 } 26 semaphore.signal() 27 } // ここまで非同期処理 28 semaphore.wait() 29}//For文終わり 30 31print(testList) //DispatchSemaphoreを使わないと[:]に、使うとたどり着かない
試したこと
semaphore.signal()やsemaphore.wait()の位置を色々変えてみた。
addSnapshotListener はdocumentなどに変更があった時に通知を受けるための関数を登録しておくものです。
登録した関数は登録時に一度呼び出された後、変更があるたびに呼ばれます。
変更があるたびに呼ばれるのでこの関数でスレッドのブロックなどを行うと問題が生じます。
この場合はおそらくgetDocument を使うべきだと思われます。(全体見ないとわからないけど)
なるほど!分かりやすくありがとうございます。
たしかにgetDocumentで良い場所でした!
まずは上記を修正します
回答1件
あなたの回答
tips
プレビュー