I was just dabbling in reference counting and was using NSString objects to understand.
1st piece of code:
NSString* a1 = [[NSString alloc] initWithString:@"abc"];
NSLog (@"%d %@ %p",[a1 retainCount],a1,a1);
NSString* a2 = [a1 copy];
NSLog (@"%d %d %@ %@ %p %p",[a1 retainCount],[a2 retainCount],a1,a2,a1,a2);
NSString* a3 = a1;
NSLog (@"%d %d %d %@ %@ %@ %p %p %p", [a1 retainCount],[a2 retainCount],[a3 retainCount],a1,a2,a3,a1,a2,a3);
NSString* a4 = [a1 retain];
NSLog (@"%d %d %d %d %@ %@ %@ %@ %p %p %p %p",[a1 retainCount],[a2 retainCount],[a3 retainCount],[a4 retainCount],a1,a2,a3,a4,a1,a2,a3,a4);
NSString* a5 = [a1 retain];
NSLog (@"%d %d %d %d %d %@ %@ %@ %@ %@ %p %p %p %p %p", [a1 retainCount],[a2 retainCount],[a3 retainCount],[a4 retainCount],[a5 retainCount],a1,a2,a3,a4,a5,a1,a2,a3,a4,a5);
This gives output:
2014-06-08 00:25:33.382 demo[13091] 1 abc 0x699100
2014-06-08 00:25:33.383 demo[13091] 2 2 abc abc 0x699100 0x699100
2014-06-08 00:25:33.383 demo[13091] 2 2 2 abc abc abc 0x699100 0x699100 0x699100
2014-06-08 00:25:33.383 demo[13091] 3 3 3 3 abc abc abc abc 0x699100 0x699100 0x699100 0x699100
2014-06-08 00:25:33.383 demo[13091] 4 4 4 4 4 abc abc abc abc abc 0x699100 0x699100 0x699100 0x699100 0x699100
This is understandable since whenever a NSString object is created (empty or with initWithString:) and copied, retained etc then reference count for that object will increase by 1 and all references will keep pointing to same object.
2nd piece of code:
NSString* a1 = [[NSString alloc] init];
a1 = @"abc";
NSLog (@"%d %@ %p",[a1 retainCount],a1,a1);
NSString* a2 = [a1 copy];
NSLog (@"%d %d %@ %@ %p %p",[a1 retainCount],[a2 retainCount],a1,a2,a1,a2);
a1 = @"xyz";
NSString* a3 = a1;
NSLog (@"%d %d %d %@ %@ %@ %p %p %p", [a1 retainCount],[a2 retainCount],[a3 retainCount],a1,a2,a3,a1,a2,a3);
a1 = @"pqr";
NSString* a4 = [a1 retain];
NSLog (@"%d %d %d %d %@ %@ %@ %@ %p %p %p %p",[a1 retainCount],[a2 retainCount],[a3 retainCount],[a4 retainCount],a1,a2,a3,a4,a1,a2,a3,a4);
a1 = @"abc";
NSString* a5 = [a1 retain];
NSLog (@"%d %d %d %d %d %@ %@ %@ %@ %@ %p %p %p %p %p", [a1 retainCount],[a2 retainCount],[a3 retainCount],[a4 retainCount],[a5 retainCount],a1,a2,a3,a4,a5,a1,a2,a3,a4,a5);
This gives output:
2014-06-08 00:27:34.940 demo[23649] 1 abc 0x601610
2014-06-08 00:27:34.941 demo[23649] 1 1 abc abc 0x601610 0x601610
2014-06-08 00:27:34.941 demo[23649] 1 1 1 xyz abc xyz 0x6015b0 0x601610 0x6015b0
2014-06-08 00:27:34.941 demo[23649] 1 1 1 1 pqr abc xyz pqr 0x601570 0x601610 0x6015b0 0x601570
2014-06-08 00:27:34.941 demo[23649] 1 1 1 1 1 abc abc xyz pqr abc 0x601610 0x601610 0x6015b0 0x601570 0x601610
Queries:
Since NSString object are immutable how is the compiler allowing me to change value of variable a1?
I have no idea how the reference count for all variables is coming out be 1 even when a5 is retaining same object which is pointed to by a1 (based on memory location)?
How are string literals stored in Objective C? I've been told they're stored on the heap but if someone could give a detailed explanation or point me in the right direction, that'd be very helpful.
Thanks in advance
Nick
For both 1 and 2: On your second block of code you're not actually changing the value of a1
. Mutability has to do with inserting or removing characters, for example.
Here you're making a1
point to a new object, which in turn should release the previous one (depending on its retain count) and retain the newly assigned.
So when you create a2
, a3
, a4
and a5
right after having a1
point to a new object each time, this new object has a retain count of 1.
For the third query, this other question might be of interest: Are NSStrings stored on the heap or on the stack and what is a good way to initialize one