ARC, gönderim kuyruklarını destekliyor mu?


95

Apple'ın "Gönderim Sıraları için Bellek Yönetimi" hakkındaki belgelerini okuyorum:

Çöp toplanan bir uygulama uygulasanız bile, gönderi kuyruklarınızı ve diğer gönderme nesnelerini yine de korumalı ve serbest bırakmalısınız. Grand Central Dispatch, belleği geri kazanmak için çöp toplama modelini desteklemez.

ARC'nin bir çöp toplayıcı olmadığını biliyorum, ancak dispatch_queue_t'mi dispatch_retain ve dispatch_release'e ihtiyacım olmadığından emin olmak istiyorum

Yanıtlar:


234

Kısa cevap: EVET, ARC gönderim sıralarını korur ve serbest bırakır.







Ve şimdi uzun cevap için…

Dağıtım hedefiniz iOS 6.0 veya Mac OS X 10.8'den düşükse

Sen kullanımına ihtiyaç dispatch_retainve dispatch_releaseSıranızdaki. ARC bunları yönetmez.

Dağıtım hedefiniz iOS 6.0 veya Mac OS X 10.8 veya üstü ise

ARC, sıranızı sizin için yönetecek. Kullanmanıza gerek yoktur (ve olamaz) dispatch_retainveya dispatch_releaseARC etkinleştirilmişse.

Detaylar

İOS 6.0 SDK ve Mac OS X 10.8 SDK'dan başlayarak, her gönderme nesnesi (a dahil dispatch_queue_t) aynı zamanda bir Objective-C nesnesidir. Bu, <os/object.h>başlık dosyasında belgelenmiştir :

 * 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.

Bu araçlar bir de Sıranıza saklayabilir NSArrayya NSDictionary, ya biriyle özelliğinde strong, weak, unsafe_unretained, assign, veya retainnitelikler. Ayrıca, sıranıza bir bloktan başvurursanız, bloğun kuyruğu otomatik olarak koruyacağı anlamına gelir.

Dolayısıyla , dağıtım hedefiniz en az iOS 6.0 veya Mac OS X 10.8 ise ve ARC'yi etkinleştirdiyseniz , ARC kuyruğunuzu koruyacak ve serbest bırakacak ve derleyici her türlü kullanma girişimini dispatch_retainveya dispatch_releasebir hata olarak işaretleyecektir.

Dağıtım hedef en az ise iOS 6.0 veya Mac OS X 10.8 ve ARC devre dışı bıraktık , el tutma ve Sıranıza salmalıdır ya arayarak dispatch_retainve dispatch_release, veya kuyruğu göndererek retainve release(gibi mesajları [queue retain]ve [queue release]).

Eski codebases ile uyumluluk için, tanımlayarak bir Objective-C nesne olarak sıranızı görmesini derleyici önleyebilir OS_OBJECT_USE_OBJCiçin 0. Örneğin, bunu .pchdosyanıza koyabilirsiniz (herhangi bir #importifadeden önce ):

#define OS_OBJECT_USE_OBJC 0

veya OS_OBJECT_USE_OBJC=0yapı ayarlarınıza önişlemci makrosu olarak ekleyebilirsiniz . Eğer ayarlarsanız OS_OBJECT_USE_OBJCiçin 0, ARC olacak değil korumak veya sizin için kuyruk bırakın ve kullanmakta kendiniz yapmak zorunda kalacaktır dispatch_retainve dispatch_release.


1
Bununla birlikte, yeni değişikliğin, gönderme nesnelerini Objective-C nesneleri olarak belirlediğini unutmayın. Bu nedenle, ARC devre dışı bırakılsa bile, bu nesneler, diğer tüm Objective-C nesneleri gibi, bir blok tarafından yakalanmışsa otomatik olarak tutulacaktır.
Jody Hagins

3
İlginç bir uç durum var. İOS 5.1 için kütüphane dağıtır ve 6.0 için uygulama ve ARC kullanıyoruz, size gerekiyorsa dispatch_release ve NULL sizin 5.1 nesne deallockodu. Aksi takdirde, bir şey (derleyici tarafından üretilen kod mu? Çalışma zamanının kendisi mi?) Nesneyi ikinci kez serbest bırakmayı deneyecektir.
Steven Fisher

Mac OS 10.7'yi kullanırken oluşturduğum diğer kaynak nesneleri göndermem gerekir mi?
p0lAris

OS X 10.7 altında tüm GCD nesnelerini manuel olarak saklamanız / serbest bırakmanız gerekir.
rob mayoff

23

Sadece buradan takip edin ... Minimum dağıtım hedefiniz iOS 6 ise, ARC artık bunları yönetiyor.


Bu aynı zamanda Mountain Lion için de geçerlidir. Dağıtım hedefiniz iOS 6 veya Mountain Lion ise, ARC altında izin verilmeyen nesneye bir yayınlama mesajı gönderen bir makro olduğu için dispatch_release'i (varsayılan olarak) kullanamazsınız.
Emil Eriksson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.