ARCはディスパッチキューをサポートしていますか?


95

「ディスパッチキューのメモリ管理」に関するアップルのドキュメントを読んでいます。

ガベージコレクションされたアプリケーションを実装する場合でも、ディスパッチキューと他のディスパッチオブジェクトを保持して解放する必要があります。Grand Central Dispatchは、メモリを再利用するためのガベージコレクションモデルをサポートしていません。

ARCはガベージコレクタではないことを知っていますが、dispatch_retainやdispatch_release my dispatch_queue_tを実行する必要がないことを確認したい

回答:


234

短い答え:はい、ARCはディスパッチキューを保持および解放します。







そして今、長い答えのために...

展開ターゲットがiOS 6.0またはMac OS X 10.8より低い場合

あなたは使用する必要がありますdispatch_retainし、dispatch_release自分のキューに。ARCはそれらを管理しません。

展開ターゲットがiOS 6.0またはMac OS X 10.8以降の場合

ARCがキューを管理します。あなたが使用(とすることはできません)する必要はありませんdispatch_retainか、dispatch_releaseARCが有効になっている場合。

細部

iOS 6.0 SDKおよびMac OS X 10.8 SDK以降、すべてのディスパッチオブジェクト(を含むdispatch_queue_t)もObjective-Cオブジェクトです。これは<os/object.h>ヘッダーファイルに記載されています。

 * By default, libSystem objects such as GCD and XPC objects are declared as
 * Objective-C types when building with an Objective-C compiler. This allows
 * them to participate in ARC, in RR management by the Blocks runtime and in
 * leaks checking by the static analyzer, and enables them to be added to Cocoa
 * collections.
 *
 * NOTE: this requires explicit cancellation of dispatch sources and xpc
 *       connections whose handler blocks capture the source/connection object,
 *       resp. ensuring that such captures do not form retain cycles (e.g. by
 *       declaring the source as __weak).
 *
 * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
 * compiler flags.
 *
 * This mode requires a platform with the modern Objective-C runtime, the
 * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
 * or iOS 6.0 deployment target.

この手段はあなたにあなたのキューを格納できるNSArrayNSDictionaryのいずれかで、またはプロパティではstrongweakunsafe_unretainedassign、またはretain属性。また、ブロックからキューを参照すると、ブロックはキューを自動的に保持します。

したがって、展開ターゲットが少なくともiOS 6.0またはMac OS X 10.8であり、ARCを有効にしている場合、ARCはキューを保持して解放し、コンパイラは使用しようとする試みdispatch_retainまたはdispatch_releaseエラーとしてフラグを立てます。

あなたのデプロイメント・ターゲットは、少なくともある場合のiOS 6.0またはMac OS X 10.8、そしてあなたは、ARCが無効になってい、手動で保持し、あなたのキューを解放しなければならないのいずれかを呼び出すことによってdispatch_retain、およびdispatch_releaseまたはキュー送信することによって、retainおよびrelease(のようなメッセージを[queue retain]して[queue release])。

古いコードベースとの互換性のために、あなたが定義することで、Objective-Cのオブジェクトとして、あなたのキューを見てから、コンパイラを防ぐことができますOS_OBJECT_USE_OBJC0。たとえば、これを.pchファイルに(#importステートメントの前に)置くことができます。

#define OS_OBJECT_USE_OBJC 0

またはOS_OBJECT_USE_OBJC=0、ビルド設定でプリプロセッサマクロとして追加できます。あなたが設定した場合OS_OBJECT_USE_OBJC0、ARCはなりません保持またはあなたのためにキューを解放し、あなたが使用してそれを自分で行う必要がありますdispatch_retaindispatch_release


1
ただし、新しい変更により、ディスパッチオブジェクトがObjective-Cオブジェクトとして指定されることに注意してください。したがって、ARCが無効になっていても、これらのオブジェクトは、他のすべてのObjective-Cオブジェクトと同様に、ブロックによってキャプチャされた場合は自動的に保持されます。
ジョディヘイギンズ2012

3
興味深いエッジケースがあります。ライブラリがiOS 5.1にデプロイされ、アプリが6.0にデプロイされており、ARCを使用しdispatch_release NULLいる場合は、5.1 deallocコード内のオブジェクトが必要です。そうでない場合、何か(コンパイラーによって生成されたコード?ランタイム自体?)がオブジェクトを再度解放しようとします。
Steven Fisher

Mac OS 10.7を使用している場合、作成した他のソースオブジェクトをディスパッチする必要がありますか?
p0lAris 2015年

OS X 10.7では、すべてのGCDオブジェクトを手動で保持/解放する必要があります。
rob mayoff 2015年

23

ここで補足します...最小の展開ターゲットがiOS 6の場合、ARCがそれらを管理します。


これはマウンテンライオンにも適用されます。展開ターゲットがiOS 6またはMountain Lionの場合、ARCで許可されていないオブジェクトにリリースメッセージを送信するマクロであるため、(デフォルトで)dispatch_releaseを使用できません。
Emil Eriksson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.