Schwach NSString-variable nicht nil ist, nach der Einstellung nur mit einer starken Referenz auf nil
Ich habe ein problem mit diesem code :
__strong NSString *yourString = @"Your String";
__weak NSString *myString = yourString;
yourString = nil;
__unsafe_unretained NSString *theirString = myString;
NSLog(@"%p %@", yourString, yourString);
NSLog(@"%p %@", myString, myString);
NSLog(@"%p %@", theirString, theirString);
Erwarte ich, dass alle Zeiger werden nil
zu dieser Zeit, aber Sie sind nicht und ich verstehe nicht, warum.
Die ersten (starken) Zeiger nil
aber die anderen beiden sind nicht. Warum ist das so?
InformationsquelleAutor marcL | 2012-06-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
tl; dr: Das problem ist, dass das string-literal wird nie veröffentlicht, damit Ihre schwachen Zeiger noch Punkte.
Theorie
Starke Variablen behalten den Wert, den Sie zeigen.
Schwach Variablen nicht Ihren Wert behalten und, wenn der Wert freigegeben ist, können Sie Ihren Zeiger auf nil (um sicher zu sein).
Unsicher unretained Werte (wie Sie wahrscheinlich Lesen können, durch den Namen) nicht behalten den Wert und wenn er freigegeben ist, tun Sie nichts über es, möglicherweise Hinweis auf ein schlechtes Stück Speicher
Literale und Konstanten
Beim erstellen einer Zeichenfolge mit
@"literal string"
es wird ein string-literal das niemals ändern wird. Wenn Sie verwenden Sie denselben string in vielen Orten in Ihrer Anwendung, es ist immer das gleiche Objekt. String-Literale geht nicht Weg. Mit[[NSString alloc] initWithString:@"literal string"]
wird keinen Unterschied machen. Da es wird ein Zeiger auf die Zeichenkette. Es ist jedoch erwähnenswert, dass[[NSString alloc] initWithFormat:@"literal string"];
funktioniert anders und wird die Freigabe seiner string-Objekt.Zeile:
Erstellen Sie einen starken Zeiger auf einen string. Dadurch wird sichergestellt, dass der Wert geht nicht Weg. In Ihrem Fall ist es etwas besonderes, da der string ist ein string-literal, das technisch nicht freigegeben.
Erstellen Sie eine schwache Zeiger auf das gleiche wie Ihre starke Zeiger. Wenn in dieser Zeit der starken Zeiger würde auf etwas anderes zeigen, den Wert, den es gerichtet ist, zu bekommen würde aufgehoben, dann wird der weak pointer ändern würde, seinen Wert, so dass Sie Punkte zu
nil
. Jetzt ist es noch Punkte die gleiche wie die starke Zeiger.Ihre starke Zeiger
nil
. Nichts weist auf den alten string, so sollte es freigesetzt werden, wenn es nicht für die Tatsache, dass es war eine literal-Zeichenfolge. Wenn Sie versucht haben, die genau die gleiche Sache mit anderen Gegenständen, die Sie selbst erstellt haben, die schwachen Variablen ändern, so dass es Punkte zunil
. Aber, da das string-literal ein literal ist und geht nicht Weg. Die schwachen variable wird immer noch auf.Einen neuen unretained-pointer erstellt, der auf Ihre schwach-pointer, die auf das string-literal.
Drucken Sie alle Ihre Saiten und verwirrt, warum der erste Wert ist
nil
aber die anderen beiden nicht.Verwandte Lesen:
Was ist der Unterschied zwischen einer string-Konstanten und string-literalen?
Sorry, Nein. Das wird auch auf die string-literal, das bedeutet, dass die schwachen Mauszeiger beim zeigen auf den starken Zeiger auf den string-literalen, die nicht weggeht.
Oh, ich habe versucht initialisiert YourString mit dieser Funktion initWithUTF8String und das Ergebnis war gut. Nur die Letzte Frage, für was Grund, es ist nicht möglich, erhalten Sie das gleiche Ergebnis mit : "initWithString" ?
Sorry, ich werde nicht in der Lage zu geben, eine gute Antwort, warum das so ist. Es ist nur die Art, wie die Dinge funktionieren. Ich kann nur vermuten, warum initWithUTF8String anders funktioniert, aber das ist nur meine Vermutungen.
Es ist eine Implementierung detail, aber
-initWithString:
ist grundsätzlich die Freigabe des Objekts auf dem Sie aufgerufen wird, kopiert das argument, und das zurück kopieren. Als eine weitere Optimierung, unveränderlichen Wert oft Objekte implementieren-copy
einfach ein-retain
da ist es egal, ob du ein "echtes" Exemplar oder einfach nur das gleiche Objekt wieder zurück. Da das original ist unveränderlich und die Kopie ist unveränderlich, Sie wird immer die gleiche sein. Schließlich, Beibehaltung ein string-literal tut nichts, weil es permanent. Alle kombiniert,-initWithString:
gegeben, ein literal gibt, das gleiche literal.InformationsquelleAutor David Rönnqvist
David ist 100% richtig in seiner Antwort. Ich habe gerade vier explizite Beispiele für die Verwendung von GHUnit.
Die Lebensdauer qualifier Verhalten bei Objekt-Referenzen.
Mit
NSObject
als proxy-Variable für alle Objekte, die das Verhalten der Lebensdauer Qualifier ist wie erwartet.Die Lebensdauer qualifier Verhalten für wörtliche
NSString
s (@"etwas").Dies ist im Grunde das gleiche wie
test_usingNSObjects
, aber statt mit einemNSObject
eineNSString
zugeordnet ist, eine literal-Zeichenfolge verwendet. Da literal-Zeichenfolgen werden nicht zerstört wie andere Objekte, verschiedene Verhaltensweisen für__weak
und__unsafe_unretained
Variablen beobachtet werden.Die Lebensdauer qualifier Verhalten für die nicht-wörtliche
NSString
s.Dies ist im Grunde das gleiche wie
test_usingNSObjects
, aber statt mit einemNSObject
eineNSString
zugeordnet ist, eine nicht-wörtliche Zeichenfolge verwendet. Da die nicht-wörtliche Zeichenfolgen zerstört werden wie andere Objekte, die Verhaltensweisen sind die gleichen, wie beobachtet, intest_usingNSObjects
.NSString
Schöpfung - die wörtliche vs. nicht-wörtliche.Zeigt Saiten auf unterschiedliche Art und Weise, wenn Sie literal noch nicht-wörtliche.
InformationsquelleAutor mmorris
die schwache Eigenschaft wird nur festgelegt werden auf null nach dem autorelease-pool abgelassen wurde.
versuchen:
InformationsquelleAutor Pizzaiola Gorgonzola