web-dev-qa-db-ja.com

ARC後のディスパッチキューにはどのプロパティを使用する必要がありますか?

私はビューコントローラーのプロパティとしてディスパッチキューを維持しています。私はビューコントローラーのinitメソッドでこのキューを1回作成し、いくつかのバックグラウンドタスクで数回再利用します。 ARCの前は、次のようにしていました。

@property (nonatomic, assign) dispatch_queue_t filterMainQueue;

そしてinit:

if (filterMainQueue == nil) {
     filterMainQueue = dispatch_queue_create("com.myQueue.CJFilterMainQueue", NULL);
}

しかし、ARCの後で、これが「割り当て」である必要があるのか​​、それとも「強力」または「弱」であるのかはわかりません。 ARCコンバータースクリプトは何も変更しませんでしたが、このキューが使用中に割り当て解除される可能性があるという事実から、微妙なバグが発生しているかどうかはわかりません。

ARCを使用する場合、3つのタイプのプロパティの違いは何ですか?また、ディスパッチキューに最適なものは何ですか?

40
Z S

更新された回答:

現在のOS XとiOSでは、DispatchオブジェクトはARCによってObj-Cオブジェクトとして扱われるようになりました。それらはObj-Cオブジェクトと同じ方法でメモリ管理され、プロパティにはstrongを使用する必要があります。

これは、OS_OBJECT_USE_OBJCで定義されている<os/object.h>マクロによって制御されます。デプロイメントターゲットがOS X 10.8以降、またはiOS 6.0以降の場合、デフォルトで1に設定されます。古いOSにデプロイしている場合、これは0に残され、以下の元の回答が表示されます。


元の答え:

ディスパッチオブジェクト(キューを含む)はObj-Cオブジェクトではないため、可能な選択肢はassignのみです。 strongまたはweakを使用しようとすると、コンパイラーはエラーをスローします。 ARCはGCDに影響を与えません。

61
Lily Ballard

IOS 6.0以上およびiOS 6.0以下のdispatch_queue_tプロパティを定義する方法は次のとおりです

#if OS_OBJECT_HAVE_OBJC_SUPPORT == 1
@property (nonatomic, strong) dispatch_queue_t serialDispatchQueue;
#else
@property (nonatomic, assign) dispatch_queue_t serialDispatchQueue;
#endif

基本的に、OS_OBJECT_HAVE_OBJC_SUPPORTは、iOS 6.0以降では1として定義されます。 (MAC 10.8以上)。 iOS 6以下では0と定義されています。

OS_OBJECT_HAVE_OBJC_SUPPORTは、GCDのようなOSオブジェクトがObjective Cをサポートすることを定義します。したがって、ARC、メモリ管理、参照カウントなどがGCDオブジェクトに適用されます。

9

これが私が使うものです:

@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue;
5
Arvin

IOS7に基づいて、dispatch_queueオブジェクトがObjective-Cオブジェクトであるかどうかをテストし、それらがすでにObjective-Cオブジェクトであることがわかりました。これを言い換えると、現在attribute((NSObject))は必要ありません。

4
Sungwook Kim

TL; DR:dispatch_queue_tは現在Objective Cオブジェクトであり、ARCで管理できます。

私はこれがどれほど前に真実であるかをテストしていませんが、iOS 7 SDKおよびXcode 5を使用して、dispatch_queue_tはオブジェクトタイプです。キューのプロパティを次のように宣言しています

@property (nonatomic, strong) dispatch_queue_t syncQueue;

コンパイラーは満足しており、すべてが期待どおりに動作します。これは以前はiOS 4または5で機能しなかったことを明確に知っています(ARC以前ではretainではなくstrongでした)。私はdispatch_queue_tの定義を詳しく調べて、これを見つけました:

/*!
 * @typedef dispatch_queue_t
 *
 * @abstract
 * Dispatch queues invoke blocks submitted to them serially in FIFO order. A
 * queue will only invoke one block at a time, but independent queues may each
 * invoke their blocks concurrently with respect to each other.
 *
 * @discussion
 * Dispatch queues are lightweight objects to which blocks may be submitted.
 * The system manages a pool of threads which process dispatch queues and
 * invoke blocks submitted to them.
 *
 * Conceptually a dispatch queue may have its own thread of execution, and
 * interaction between queues is highly asynchronous.
 *
 * Dispatch queues are reference counted via calls to dispatch_retain() and
 * dispatch_release(). Pending blocks submitted to a queue also hold a
 * reference to the queue until they have finished. Once all references to a
 * queue have been released, the queue will be deallocated by the system.
 */
DISPATCH_DECL(dispatch_queue);

その音で機能しないので、DISPATCH_DECLの定義を確認したところ、次のことがわかりました。

/*
 * By default, dispatch 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.
 * See <os/object.h> for details.
 */
1
Holly