web-dev-qa-db-ja.com

Swift 3のDispatchQueueのAutoreleaseFrequency

Xcode 8ベータ5では、DispatchQueueの初期化子が変更され、qos(サービス品質)、属性、および自動解放頻度の個別の引数を受け入れるようになりました。新しいイニシャライザーで動作するようにコードを変換することに問題はありませんでしたが、いくつかの属性の意味、特に自動解放の頻度についてはよくわかりません。

たとえば、Xcode8ベータ3およびSwift 3では、シリアルDispatchQueueを次のように作成できました。

let serialQueue = DispatchQueue(label: "Concurrent Map", attributes: [.serial, .qosBackground], target: nil)

Xcode8ベータ5およびSwift 3:

let serialQueue = DispatchQueue(label: "Concurrent Map", qos: .background, attributes: [], autoreleaseFrequency: .inherit, target: nil)

私の質問は次のとおりです。

  • 新しいDispatchQueue.Attributesでは、.serialはメンバーではなくなりました。これは、.concurrentがないことでシリアルキューが作成されることを意味しますか?私がSwift Playgroundsで行った最初のテストはこれを確認しているようです。他の誰かが確認できますか?
  • DispatchQueue.AutoreleaseFrequencyは、.inherit、.never、および.workItemを持つ新しいタイプであることがわかります。これらはどういう意味ですか?私はGCDと自動解放についていくつかの調査を行いましたが、自動解放プールの概念についてはあまり詳しくありません。
17
Matthew Seaman

これらの新しい属性の公式ドキュメントは見つかりませんでした(おそらく作業中です)が、既存のGCDドキュメントを考えると、行間を読むと、ここで意図されていることを直感的に理解するのは非常に簡単です。

新しいDispatchQueue.Attributesでは、.serialはメンバーではなくなりました。これは、.concurrentがないことでシリアルキューが作成されることを意味しますか? Swift Playgroundsで行った最初のテストで、これが確認されたようです。他の誰かが確認できますか?

はい。キューはシリアルまたはコンカレントのいずれかです。作成するほとんどのキューはシリアルであるため、デフォルトの動作が必要ない場合にのみ、それらをコンカレントに設定する必要があります。

DispatchQueue.AutoreleaseFrequencyは、.inherit、.never、および.workItemを持つ新しいタイプであることがわかります。これらはどういう意味ですか?私はGCDと自動解放についていくつかの調査を行いましたが、自動解放プールの概念についてはあまり詳しくありません。

以前は、DispatchQueuesは不特定の時間(スレッドが非アクティブになったとき)に自動解放プールをポップしていました。実際には、これは、送信したディスパッチアイテムごとに自動解放プールを作成するか、自動解放されたオブジェクトが予測できない時間ぶらぶらすることを意味しました。

非決定論は(特に並行性ライブラリでは)持つのは素晴らしいことではないので、次の3つの動作のいずれかを指定できるようになりました。

.inherit:わからない、おそらく以前のデフォルトの動作

.workItem:実行される各アイテムの自動解放プールを作成して排出します

.never:GCDは自動リリースプールを管理しません

これらすべてのうち、.workItemのみを使用することをお勧めします。これは、アイテムの完了時に一時オブジェクトがクリーンアップされるためです。他のオプションは、おそらく、古い動作に依存するバグのあるコード、または実際にこのようなものを自分で管理したいまれなユーザーのいずれかのためのものです。


実際、もう少し考えてみると、Swiftのみの作業項目(Objective-Cコードを呼び出さない)を送信する場合、おそらく安全で正しいことはありません。 Swift標準ライブラリクラスのいずれか/すべてがObjective-Cコードを呼び出す可能性があることを考えると、これを完全に独自のSwiftコード内にある計算に制限することをお勧めします。

14
Mark Bessey

彼が言ったように、私はマークによって与えられた答えを「主観的」だと思います、公式の文書はまだ文書に出ていません。ただし、公式のドキュメントはコードで見つけることができるので、意見ではなくコードのドキュメントにあるものに純粋に基づいているので、正しい答えであると私が信じているものを示しています。ここにあります:

DISPATCH_AUTORELEASE_FREQUENCY_INHERITこの自動解放頻度のディスパッチキューは、ターゲットキューから動作を継承します。これは、手動で作成されたキューのデフォルトの動作です。

DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEMこの自動解放頻度でキューをディスパッチします非同期で送信されたすべてのブロックの実行の前後に自動解放プールをプッシュおよびポップします。

DISPATCH_AUTORELEASE_FREQUENCY_NEVERこの自動解放頻度のディスパッチキューは、非同期で送信されたブロックの実行の前後に個別の自動解放プールを設定することはありません。これは、グローバル同時キューの動作です。

30
zumzum