私はシリアルDispatchQueueを使用してPHAssetsのセットを読み取り、それをリモートホストに1つずつアップロードしています。コールバックはどのキューで実行されますか?
コードではPHAsset.fetchAssets()を使用し、次にenumerateObjects内でqueue.async { .. }
を使用してキューにタスクを追加します。タスク内では、PHImageManager.default().requestImageData
を使用しています。これは、アセットの内容を読み取り、クロージャを実行してData
として返します。
ので、キューに入れられたタスクの各々の中に終わるコードは次のようになります。私は実行している
let queue = DispatchQueue(
label: "com.myapp.asset_upload_queue",
qos: .background
)
問題:
self.queue.async {
PHImageManager.default().requestImageData(
for: asset,
options: self.imageRequestOptions()) { (data: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable : Any]?) in
print("--> Upload data: \(data?.description ?? "n/a")")
usleep(2000000)
}
}
マイキューは、次のように定義されていますすぐにPHImageManager.requestImageData
が返ってくるので、次のタスクはすぐにデータを読み始めます。最終結果は複数の同時アップロードで終わり、CPUは全面的に屋根を撃ちます。
コールバックPHImageManager.requestImageData
take isがキュースレッドをブロックしないため、次のタスクに移動することが問題であると想定します。その次の作業はすぐにデータの読み込みを開始します。
私はのように、キューにあるコールバックの内側に何入れてみました:これはシリアルアップロードの実行を開始しますが、requestImageData
呼び出しがまだ次々に実行されている、巨大な負担をかけるどの
self.queue.async {
PHImageManager.default().requestImageData(
for: asset,
options: self.imageRequestOptions()) { (data: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable : Any]?) in
self.queue.async {
print("--> Upload data: \(data?.description ?? "n/a")")
usleep(2000000)
}
}
}
CPU上で実行します。
質問:
前回のアップロードが完了するとrequestImageData
のみ実行されますように私は流れを制御する方法を?
他のもの、私が試した
私の最初のアプローチは伝えrequestContentEditingInputWithOptions
を使用して行うことができget an asset path directly from the Photos frameworkを、試してみてすることでした。しかし、私はそれを実際のデバイスではなくシミュレータ上で動作させることしかできませんでした。