ARC รองรับคิวการจัดส่งหรือไม่


95

ฉันกำลังอ่านเอกสารของ Apple เกี่ยวกับ "Memory Management for Dispatch Queues":

แม้ว่าคุณจะใช้แอปพลิเคชันที่เก็บรวบรวมขยะคุณยังต้องรักษาและปล่อยคิวการจัดส่งและวัตถุจัดส่งอื่น Grand Central Dispatch ไม่รองรับโมเดลการรวบรวมขยะสำหรับการเรียกคืนหน่วยความจำ

ฉันรู้ว่า ARC ไม่ใช่คนเก็บขยะ แต่ฉันอยากแน่ใจว่าฉันไม่จำเป็นต้อง dispatch_retain และ dispatch_release 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_releaseหากเปิดใช้งาน ARC

รายละเอียด

เริ่มต้นใน iOS 6.0 SDK และ MacOS X 10.8 SDK ทุกออบเจ็กต์การจัดส่ง (รวมถึง a 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.

ซึ่งหมายความว่าคุณสามารถจัดเก็บคิวของคุณในNSArrayหรือNSDictionaryหรือในสถานที่ให้กับหนึ่งในที่strong, weak, unsafe_unretained, assignหรือ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_OBJCเป็น0. ตัวอย่างเช่นคุณสามารถใส่สิ่งนี้ใน.pchไฟล์ของคุณ(ก่อน#importคำสั่งใด ๆ):

#define OS_OBJECT_USE_OBJC 0

หรือคุณสามารถเพิ่มOS_OBJECT_USE_OBJC=0เป็นมาโครตัวประมวลผลล่วงหน้าในการตั้งค่าบิลด์ของคุณ ถ้าคุณตั้งค่าOS_OBJECT_USE_OBJCที่จะ0โค้งจะไม่เก็บหรือปล่อยคิวของคุณสำหรับคุณและคุณจะต้องทำมันด้วยตัวคุณเองโดยใช้และdispatch_retaindispatch_release


1
อย่างไรก็ตามโปรดทราบว่าการเปลี่ยนแปลงใหม่กำหนดให้ส่งวัตถุเป็นวัตถุ Objective-C ดังนั้นแม้ว่า ARC จะถูกปิดใช้งานวัตถุเหล่านี้จะถูกเก็บไว้โดยอัตโนมัติหากถูกบล็อกเช่นเดียวกับวัตถุ Objective-C อื่น ๆ
Jody Hagins

3
มีเคสขอบที่น่าสนใจ หากไลบรารีของคุณปรับใช้กับ iOS 5.1 และแอปของคุณเป็น 6.0 และคุณกำลังใช้ ARC คุณจะต้องdispatch_release และ NULLวัตถุในdeallocโค้ด5.1 ของคุณ มิฉะนั้นบางอย่าง (โค้ดที่สร้างโดยคอมไพเลอร์รันไทม์เอง?) จะพยายามปล่อยอ็อบเจ็กต์เป็นครั้งที่สอง
Steven Fisher

ฉันจำเป็นต้องส่งอ็อบเจ็กต์ต้นทางอื่นที่ฉันสร้างเมื่อใช้ Mac OS 10.7 หรือไม่
p0lAris

คุณต้องเก็บ / ปล่อยวัตถุ GCD ทั้งหมดด้วยตนเองภายใต้ OS X 10.7
rob mayoff

23

เพียงติดตามที่นี่ ... หากเป้าหมายการปรับใช้ขั้นต่ำของคุณคือ iOS 6 ตอนนี้ ARC จะจัดการพวกเขา


นอกจากนี้ยังใช้กับ Mountain Lion หากเป้าหมายการปรับใช้ของคุณคือ iOS 6 หรือ Mountain Lion คุณไม่สามารถ (โดยค่าเริ่มต้น) ใช้ dispatch_release เนื่องจากเป็นมาโครที่ส่งข้อความเผยแพร่ไปยังวัตถุซึ่งไม่ได้รับอนุญาตภายใต้ ARC
Emil Eriksson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.