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

flagg19
quelle

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.

Rob Mayoff
quelle
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.

kcharwood
quelle
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