Der LLVM Compiler 3.0 stellt vier neue Eigentümer - Qualifikation: __strong
, __autoreleasing
, __unsafe_unretained
, und __weak
. Die ersten drei sind gemäß Spezifikation auch außerhalb von ARC erhältlich .
Wie Joshua angibt, sind standardmäßig alle Zeiger __strong
unter ARC. Dies bedeutet, dass ein Objekt, das diesem Zeiger zugewiesen ist, so lange beibehalten wird, wie dieser Zeiger darauf verweist. Dies ist für die meisten Dinge in Ordnung, eröffnet jedoch die Möglichkeit, Zyklen beizubehalten, wie ich in meiner Antwort hier beschreibe . Wenn Sie beispielsweise ein Objekt haben, das ein anderes Objekt als Instanzvariable enthält, dieses zweite Objekt jedoch eine starke Verknüpfung zum ersten Objekt als Delegat aufweist, werden die beiden Objekte niemals freigegeben.
Aus diesem Grund existieren die __unsafe_unretained
und __weak
Qualifikanten. Sie werden am häufigsten für Delegaten verwendet, bei denen Sie eine Eigenschaft für diesen Delegaten mit dem Attribut weak
oder definieren unsafe_unretained
( assign
effektiv unsafe_unretained
) und diese dann durch Markieren der jeweiligen Instanzvariablen mit __weak
oder abgleichen __unsafe_unretained
. Dies bedeutet, dass die Delegateninstanzvariable weiterhin auf das erste Objekt verweist, dieses Objekt jedoch nicht beibehalten wird, wodurch der Aufbewahrungszyklus unterbrochen wird und beide Objekte freigegeben werden können.
Abgesehen von Delegierten ist dies nützlich, um andere Aufbewahrungszyklen zu unterbrechen, die sich möglicherweise in Ihrem Code bilden. Das Leaks-Instrument enthält jetzt eine Zyklenansicht, in der die in Ihrer Anwendung erkannten Aufbewahrungszyklen grafisch angezeigt werden.
Beides __unsafe_unretained
und __weak
verhindern das Zurückhalten von Objekten, jedoch auf leicht unterschiedliche Weise. Denn __weak
der Zeiger auf ein Objekt wird nil
bei der Freigabe des Objekts , auf das er zeigt, konvertiert , was ein sehr sicheres Verhalten ist. Wie der Name schon sagt, __unsafe_unretained
wird weiterhin auf den Speicher verwiesen, in dem sich ein Objekt befand, auch nachdem es freigegeben wurde. Dies kann zu Abstürzen führen, wenn auf das freigegebene Objekt zugegriffen wird.
Warum würden Sie dann jemals verwenden __unsafe_unretained
? Leider __weak
wird nur für iOS 5.0 und Lion als Bereitstellungsziele unterstützt. Wenn Sie auf iOS 4.0 und Snow Leopard zurückgreifen möchten, müssen Sie das __unsafe_unretained
Qualifikationsmerkmal oder etwas wie Mike Ashs MAZeroingWeakRef verwenden .
__unsafe_unretained
kann es nützlich sein, C-Arrays vonNSString
Konstanten und dergleichen zu definieren, z. B.NSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };
__weak
als Qualifikationsmerkmal angeben , damit diese Art von Zeigern verwendet werden kann. Sie können immer noch__unsafe_unretained
mit einem reinen 5.0-Ziel verwenden und es verhält sich nicht so__weak
. Wenn Sie etwas möchten, das zwischen den beiden Modi wechselt, je nachdem, ob Ihr Ziel dies unterstützt, können Sie eine compilerspezifische Definition verwenden, wie ich sie hier vorschlage: stackoverflow.com/a/8594878/19679NSString *myStrings = { @"Foo", @"Bar" };
ist keine gültige Objective-C-Syntax;@"Foo"
hat TypNSString*
für sich. Vielleicht hast du es gemeintNSString *myStrings[] = { @"Foo", @"Bar" };
, aber in diesem Fall verstehe ich nicht wirklich, wie__unsafe_unretained
es besonders nützlich wäre.__unsafe_unretained
C-Struktur-Mitglieder nützlich sein können, die auf NSString-Konstanten verweisen, z. B.struct foo { __unsafe_unretained NSString * const s; int x; };
Class
. Siehe: stackoverflow.com/a/14245894/392847weak
Objekte verwenden, die Sie nicht besitzen.unsafe_unretained
auf dem Grundstück verwenden.unsafe_unretained
Gegenstände genau so sindweak
, ohne die zusätzliche Sicherheit, sie zu löschen, wenn der Gegenstand, auf den sie zeigen, freigegeben wird (und der damit verbundene Overhead).quelle
unsafe_unretained
Ivars, wenn zur Laufzeit gesetzt, verhalten sich genauso wiestrong
diejenigen, die führt mich zu glauben , dassunsafe_unretained
ist einfach ein Compiler Hinweis, während schwach ist , nicht. Weitere Informationen hier: stackoverflow.com/questions/11621028/…__unsafe_unretained
ist identisch mit dem Standardspeicher eines Objekts vor ARC. Bei ARC bedeutet die Standardeinstellung jetzt,__strong
dass Sie eine Referenz darauf haben, bis Ihre Referenz den Gültigkeitsbereich verlässt.quelle
Eine weitere Beobachtung zu __unsafe_unretained: Ich habe Abstürze in meiner App auf dem Gerät und NICHT im Simulator mit iVars, die als __unsafe_unretained deklariert sind! Ja, es war ein Fehler im Code der ARC-Migration, aber es war das erste Mal, dass ich einen solchen Unterschied zwischen Gerät und Simulator bemerkte.
quelle