Ich habe ARC ausgeschaltet.
Ich habe eine Eigenschaft in einer Klasse wie folgt deklariert:
%Vor% Ich setze name
mit einer konstanten Zeichenkette:
Ich habe dealloc
für meine Klasse wie folgt implementiert:
Ich habe erwartet, dass es ein Speicherleck geben würde, weil ich name
nicht freigegeben habe. Ich verwende Xcode 6.2 und Product>Analyze
identifiziert keine Lecks, und auch nicht Instrumente: Product>Profile, choose Leaks, hit the red Record button
.
Hier ist der relevante Code:
%Vor%....
%Vor%...
%Vor% Nachdem ich eine Weile darüber nachgedacht habe, ist die einzige Erklärung, die ich finden kann, dass name setter
nicht tatsächlich die konstante Zeichenkette kopiert. Es sieht so aus, als ob Obj-C eine Typprüfung auf the string being assigned
für die Eigenschaft durchführt, und weil es eine konstante Zeichenkette ist, weist Obj-C (%) the-pointer-to-the-constant-string
nur der name-pointer
zu. Geht so etwas weiter?
Hier gibt es zwei Optimierungen, die zusammen dieses Ergebnis bewirken.
Erstens: NSString-Literale werden in einem speziellen Segment der Binärdatei gespeichert und nicht zur Laufzeit zugewiesen. Sie ignorieren Retain und Release und werden niemals zugewiesen oder freigegeben.
Zweitens: Wenn Sie einen unveränderlichen NSString (einschließlich eines String-Literals) kopieren, behalten Sie ihn stattdessen bei, da die Kopie garantiert immer identisch mit dem Original ist. (Dies wird erreicht, indem die Methoden -ezugen und -freigeben in der privaten NSString-Unterklasse überschrieben werden)
In Ihrem Szenario wird die Kopie also zu einem Retain, der Retain wird ignoriert, und die Aufhebung der Zuordnung wird nicht ausgeführt, selbst wenn Sie die Zeichenfolge in dealloc ordnungsgemäß freigegeben haben.
Tags und Links memory-leaks objective-c ios8