Pointer-Frage (Objective-C)

123

Aktives Mitglied
Thread Starter
Dabei seit
08.12.2008
Beiträge
1.901
Reaktionspunkte
25
Hallo,

müsste bei dem Code nicht bei beiden NSLog-Befehlen (sowohl beim Pointer, als auch beim Inhalt) das Selbe rauskommen?

Code:
        NSString *test = @"test";
        NSString *test2 = test;
        
        test = @"geändert";
        
        NSLog(@"Pointer von test: %p , inhalt von test: %@", test, test);
        NSLog(@"Pointer von test2 %p , inhalt von test2 %@", test2, test2);

In der Variablen test2 (vom Typ NSString) speichere ich doch nur die Speicheradresse (nicht die Zeichenkette) von der Variablen test.
Danach ändere ich die Zeichenkette, die hinter der Speicheradresse steht.

Nach meiner Meinung, müsste also der 1. und der 2. NSLog-Befehl sowohl von der Pointeradresse als auch vom Inhalt (der Zeichenkette) exakt das Gleiche liefern. Das tut er aber nicht.

Er verhält sich meiner Meinung nach so, als hätte ich geschrieben:
Code:
NSString *test2 = [test copy];
 
NSString ist immutable - also nicht veränderbar.

Mit
Code:
test = @"geändert";
erzeugst du wieder einen neuen String und zeigst mit test auf diesen neuen String. Den bestehenden änderst du damit aber nicht.

test2 zeigt hingegen immer noch auf die alte Instanz.
 
Okay, das klingt logisch. Aber was bewirkt dann dieser Befehl (mit dem copy)?

NSString *test2 = [test copy];
 
Okay, das klingt logisch. Aber was bewirkt dann dieser Befehl (mit dem copy)?

NSString *test2 = [test copy];

Mach den Versuch in Deinem Beispiel doch stattdessen mit einem NSMutableString. Dann sollte es klar sein?

Code:
NSMutableString *test = [NSMutableString stringWithString:@"test"];
NSString *test2 = test; // [test mutableCopy];
    
[(NSMutableString*)test2 appendString:@"geändert"];
    
NSLog(@"Pointer von test: %p , inhalt von test: %@", test, test);
NSLog(@"Pointer von test2 %p , inhalt von test2 %@", test2, test2);
 
Zuletzt bearbeitet:
Okay, das klingt logisch. Aber was bewirkt dann dieser Befehl (mit dem copy)?

NSString *test2 = [test copy];

Das ist ja das interessante. Im Fall von "immutable" Objecten wird eben bei "copy" keine Kopie erzeugt.
Nur der Referenz Zähler wird erhöht. (ohne ARC)

Code:
    NSString *s1 = @"Hallo";
    NSString *s2 = @"Welt";
    NSString *s3;
    NSString *s4;

    NSLog(@"Hallo"); // Selbst diese Instanz ist identisch mit 's1', da der Compiler schlau ist
    NSLog(@"Welt");  // Dasselbe gilt hier bei 's2'

    NSLog(@"%p %p", s1, s2);

    s2 = [s1 copy];
    s3 = [s1 copy];
    s4 = [s1 copy];

    NSLog(@"%p %p %p %p", s1, s2, s3, s4);

Im obigen Beispiel zeigen alle NSString Instanzen trotz "copy" auf dieselbe Instanz, weil sie eben nicht veränderbar ist.
Schaut man sich das Assembler Listing an, sieht man sogar, dass @"Hallo" und @"Welt", die als sogenannte String-Literale im Code vorkommen,
auf s1 und s2 verweisen, da der Compiler weiss das sie zur Laufzeit immer konstant bleiben.

Code:
	.section	__TEXT,__cstring,cstring_literals
l_.str:                                 ## @.str
	.asciz	 "Hallo"

	.section	__DATA,__cfstring
	.align	4                       ## @_unnamed_cfstring_


// Das ist die Referenz die in NSLog(@"Hallo"); auf s1 zeigt.

__unnamed_cfstring_4:
	.quad	___CFConstantStringClassReference
	.long	1992                    ## 0x7c8
	.space	4
	.quad	l_.str3
	.quad	5                       ## 0x5

	.section	__TEXT,__objc_methname,cstring_literals
 
Okan, danke.
Mit dem NSMutableString ist mir einiges klar geworden.
Und bei immutable-Objekten wird einfach der retain-Zähler um 1 erhöht, da eine wirkliche Kopie in eine neue Speicheradresse ja unsinnig währe.
 
Zurück
Oben Unten