Warum kein Speicherleck für: @property (copy) NSString * name, wenn ich ihn nicht in dealloc veröffentliche?

8

Ich habe ARC ausgeschaltet.

Ich habe eine Eigenschaft in einer Klasse wie folgt deklariert:

%Vor%

Ich setze name mit einer konstanten Zeichenkette:

%Vor%

Ich habe dealloc für meine Klasse wie folgt implementiert:

%Vor%

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?

    
7stud 27.04.2015, 21:10
quelle

1 Antwort

10

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.

    
Catfish_Man 27.04.2015, 21:16
quelle

Tags und Links