Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused by NSString immutability

I am an Objective-C newbie. I am struggling with the twin concepts of mutability/immutability. I am ploughing through a book called Programming in Objective-C 4th Edition. Chapter 15 talks about the NSString class which is stated to be immutable. The book then provides examples which seem to contradict that e.g.:

NSString *str1 = @"this is string A";
NSString *str2 = @"this is string B";

str2 = [str1 stringByAppendingString:str2];

NSString *res; 

res = [str1 substringToIndex:3];
res = [str1 substringFromIndex:5];
res = [[str1 substringFromIndex:8]substringToIndex:6];
res = [str1 substringWithRange:NSMakeRange(8, 6)];

So even though 'res' is a pointer to an immutable object, its value has changed several times, so how can this be called immutable? I guess I am completely missing the point. Any advice, gratefully received.

like image 727
Adam Strait Avatar asked Nov 27 '25 15:11

Adam Strait


1 Answers

In the following lines:

NSString *str2 = @"this is string B";
str2 = [str1 stringByAppendingString:str2];

You don't change the content of the string "this is string B" (that were stored in variable str2), you make the variable str2 point to a different string (a new string that is generated by the stringByAppendingString: method).

The difference here is quite the same as in C between const char* and char* const.

  • NSString* and const char* both denote a pointer to a string (Cocoa or C resp.) whose content can't be changed. The variable can still point to a different string, but the original string won't change its content.
  • That's different from a constant pointer to a string like char* const or NSMutableString* const, which is a constant pointer to a mutable string, meaning the content of the string itself can be changed, but the variable/pointer will always point to the same address in memory.

Study this example:

NSString* str1 = @"A";
NSString* str2 = str1; // points to the same immutable string
NSString* str3 = [str1 stringByAppendingString:@"B"];
// Now str1 and str2 both point to the string "A" and str3 points to a new string "AB"
str2 = str3;
// Now str2 points to the same string as str3 (same memory address and all)
// So str1 points to string "A" and str2 and str3 both point to "B"

Note that in that example, str1 hasn't changed and is still "A". It has not been mutated. This is different than with this other example:

NSMutableString* str1 = [NSMutableString stringWithString:@"A"];
NSMutableString* str2 = str1; // points to the same mutable string
[str2 appendString:@"B"];
// Now str1 and str2 still both point to the same string, but
// this same string has been mutated and is now "AB"
// So the string that previously was "A" is now "AB" but is still as the same address in memory
// and both str1 and str2 points to this address so are BOTH equal to string "AB"

In this second example, the string is mutated, so both variables str1 and str2 that are pointing to this string now contains "AB".

like image 66
AliSoftware Avatar answered Nov 29 '25 15:11

AliSoftware



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!