Ich versuche das Rätsel zu lösen.
__strong
ist die Standardeinstellung für alle Objektiv-C-Objektzeiger wie NSObject, NSString usw. Es ist eine starke Referenz. ARC gleicht es mit einem -release
am Ende des Bereichs aus.
__unsafe_unretained
entspricht dem alten Weg. Es wird für einen schwachen Zeiger verwendet, ohne das beibehaltene Objekt beizubehalten.
__weak
ist wie mit der __unsafe_unretained
Ausnahme, dass es sich um eine schwache Referenz mit automatischer Nullung handelt, was bedeutet, dass der Zeiger auf Null gesetzt wird, sobald die Zuordnung des referenzierten Objekts aufgehoben wird. Dadurch wird die Gefahr von baumelnden Zeigern und EXC_BAD_ACCESS-Fehlern ausgeschlossen.
Aber wofür genau ist __autoreleasing
gut? Es fällt mir schwer, praktische Beispiele zu finden, wann ich dieses Qualifikationsmerkmal verwenden muss. Ich glaube, es ist nur für Funktionen und Methoden, die einen Zeiger-Zeiger erwarten, wie:
- (BOOL)save:(NSError**);
oder
NSError *error = nil;
[database save:&error];
was unter ARC folgendermaßen deklariert werden muss:
- (BOOL)save:(NSError* __autoreleasing *);
Aber das ist zu vage und ich würde gerne verstehen, warum . Die Code-Schnipsel, die ich finde, platzieren das __autoreleasing zwischen den beiden Sternen, was für mich seltsam aussieht. Der Typ ist NSError**
(ein Zeiger-Zeiger auf NSError). Warum also __autoreleasing
zwischen den Sternen und nicht einfach vor NSError**
?
Es kann auch andere Situationen geben, auf die ich mich verlassen muss __autoreleasing
.
quelle
Antworten:
Du hast recht. Wie die offizielle Dokumentation erklärt:
All dies wird im ARC-Übergangsleitfaden sehr gut erklärt .
In Ihrem NSError-Beispiel bedeutet die Deklaration
__strong
implizit:Wird umgewandelt in:
Wenn Sie Ihre
save
Methode aufrufen :Der Compiler muss dann eine temporäre Variable erstellen, die auf festgelegt ist
__autoreleasing
. So:Wird umgewandelt in:
Sie können dies vermeiden, indem Sie das Fehlerobjekt
__autoreleasing
direkt als deklarieren .quelle
__autoreleasing
wird nur für Argumente verwendet, die als Referenz übergeben werden. Dies ist ein Sonderfall, da Sie einen Zeiger auf den Zeiger eines Objekts haben. Dies ist bei Convenience-Konstruktoren nicht der Fall, da sie nur einen Zeiger auf ein Objekt zurückgeben und von ARC automatisch verarbeitet werden.Nachverfolgung der Antwort von Macmade und der Anschlussfrage des stolzen Mitglieds in den Kommentaren (hätte dies auch als Kommentar gepostet, aber es überschreitet die maximale Anzahl von Zeichen):
Aus diesem Grund wird das variable Qualifikationsmerkmal von __autoreleasing zwischen den beiden Sternen platziert.
Zum Vorwort lautet die korrekte Syntax zum Deklarieren eines Objektzeigers mit einem Qualifizierer:
Der Compiler wird dies vergeben:
aber es ist nicht richtig. Weitere Informationen finden Sie in der Apple ARC-Übergangsanleitung (lesen Sie den Abschnitt "Sie sollten Variablen korrekt dekorieren ...").
So beantworten Sie die vorliegende Frage: Ein Doppelzeiger kann kein ARC-Speicherverwaltungsqualifikationsmerkmal haben, da ein Zeiger, der auf eine Speicheradresse zeigt, ein Zeiger auf einen primitiven Typ und kein Zeiger auf ein Objekt ist. Wenn Sie jedoch einen Doppelzeiger deklarieren, möchte ARC wissen, welche Speicherverwaltungsregeln für den zweiten Zeiger gelten. Aus diesem Grund werden Doppelzeigervariablen wie folgt angegeben:
Im Fall eines Methodenarguments, das ein doppelter NSError-Zeiger ist, wird der Datentyp wie folgt deklariert:
was auf Englisch "Zeiger auf einen __autoreleasing NSError-Objektzeiger" sagt.
quelle
Die endgültige ARC-Spezifikation besagt dies
So zum Beispiel der Code
wird tatsächlich konvertiert zu
... weshalb es funktioniert, wenn Sie einen Parameter haben
NSError* __autoreleasing * errorPointer
, die aufgerufene Methode weist dann den Fehler zu*errorPointer
und die obige Semantik wird aktiviert.Sie könnten
__autoreleasing
in einem anderen Kontext ein ARC-Objekt in den Autorelease-Pool zwingen, aber das ist nicht besonders nützlich, da ARC den Autorelease-Pool nur bei der Methodenrückgabe zu verwenden scheint und dies bereits automatisch verarbeitet.quelle