Unterstützt ARC Versandwarteschlangen?


95

Ich lese die Dokumentation von Apple zum Thema "Speicherverwaltung für Versandwarteschlangen":

Selbst wenn Sie eine durch Müll gesammelte Anwendung implementieren, müssen Sie Ihre Versandwarteschlangen und andere Versandobjekte beibehalten und freigeben. Grand Central Dispatch unterstützt das Garbage Collection-Modell zum Zurückfordern von Speicher nicht.

Ich weiß, dass ARC kein Garbage Collector ist, aber ich möchte sichergehen, dass ich meine dispatch_queue_t nicht dispatch_retain und dispatch_release muss

Antworten:


234

Die kurze Antwort: JA, ARC behält die Versandwarteschlangen bei und gibt sie frei.







Und jetzt zur langen Antwort…

Wenn Ihr Bereitstellungsziel niedriger als iOS 6.0 oder Mac OS X 10.8 ist

Sie müssen dispatch_retainund verwendendispatch_release in Ihrer Warteschlange verwenden. ARC verwaltet sie nicht.

Wenn Ihr Bereitstellungsziel iOS 6.0 oder Mac OS X 10.8 oder höher ist

ARC verwaltet Ihre Warteschlange für Sie. Sie müssen oder können dispatch_retainoder nicht verwendendispatch_release wenn ARC aktiviert ist.

Einzelheiten

Ab dem iOS 6.0 SDK und dem Mac OS X 10.8 SDK ist jedes Versandobjekt (einschließlich a dispatch_queue_t) auch ein Objective-C-Objekt. Dies ist in der <os/object.h>Header-Datei dokumentiert :

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

Diese Mittel können Sie speichern Ihre Warteschlange in ein NSArrayoder NSDictionary, oder in einem Haus mit einem der strong, weak, unsafe_unretained, assign, oder retainAttribute. Dies bedeutet auch, dass der Block die Warteschlange automatisch beibehält, wenn Sie von einem Block aus auf Ihre Warteschlange verweisen.

Also , wenn Ihr Implementierungsziel ist mindestens iOS 6.0 oder Mac OS X 10.8, und Sie haben ARC aktiviert , wird ARC behalten und Ihre Warteschlange freizugeben, und der Compiler - Flag jeden Versuch zu verwenden dispatch_retainoder dispatch_releaseals Fehler.

Wenn Ihre Bereitstellung Ziel mindestens iOS 6.0 oder Mac OS X 10.8, und Sie haben ARC deaktiviert , müssen Sie manuell beibehalten und Ihre Warteschlange freizugeben, entweder durch den Aufruf dispatch_retainund dispatch_release, oder durch die Warteschlange zu senden retainund releaseNachrichten (wie [queue retain]und [queue release]).

Aus Gründen der Kompatibilität mit alten Codebasen können Sie verhindern, dass der Compiler Ihre Warteschlange als Objective-C-Objekt sieht, indem Sie OS_OBJECT_USE_OBJCto definieren 0. Zum Beispiel können Sie dies in Ihre .pchDatei einfügen (vor allen #importAnweisungen):

#define OS_OBJECT_USE_OBJC 0

oder Sie können OS_OBJECT_USE_OBJC=0in Ihren Build-Einstellungen ein Präprozessor-Makro hinzufügen . Wenn Sie festgelegt OS_OBJECT_USE_OBJCzu 0werden ARC nicht behalten oder lassen Sie die Warteschlange für Sie, und Sie werden es zu tun haben , sich mit dispatch_retainund dispatch_release.


1
Beachten Sie jedoch, dass die neue Änderung Versandobjekte als Objective-C-Objekte bezeichnet. Selbst wenn ARC deaktiviert ist, bleiben diese Objekte automatisch erhalten, wenn sie von einem Block erfasst werden - genau wie alle anderen Objective-C-Objekte.
— Jody Hagins

3
Es gibt einen interessanten Randfall. Wenn Ihre Bibliothek auf iOS 5.1 und Ihre App auf 6.0 bereitgestellt wird und Sie ARC verwenden, müssen Sie dispatch_release und NULL das Objekt in Ihrem 5.1- deallocCode. Andernfalls versucht etwas (vom Compiler generierter Code? Die Laufzeit selbst?), Das Objekt ein zweites Mal freizugeben.
— Steven Fisher

Muss ich andere Quellobjekte versenden, die ich unter Mac OS 10.7 erstellt habe?
— p0lAris

Sie müssen alle GCD-Objekte unter OS X 10.7 manuell beibehalten / freigeben.
— Rob Mayoff

23

Nur eine Folge hier ... Wenn Ihr Mindestbereitstellungsziel iOS 6 ist, verwaltet ARC diese jetzt.


Dies gilt auch für Mountain Lion. Wenn Ihr Bereitstellungsziel iOS 6 oder Mountain Lion ist, können Sie dispatch_release (standardmäßig) nicht verwenden, da dies ein Makro ist, das eine Freigabemeldung an das Objekt sendet, das unter ARC nicht zulässig ist.
— Emil Eriksson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.