Question

There are many posts about the same topic and it may be a stupid question, but I haven't been able to understand this concept.

I know the problems presented when you assign a mutable string to a immutable one, and why I should use copy to avoid these problems.

What I don't really understand is: what does exactly mean that a NSString cannot be modified?

If I do this:

NSString *foo = @"Hello World!";
foo = @"Hello everybody!";

I understand I'm not modifying foo's value, but rather replacing the old instance with a new one. But then, how is it defined that I cannot rewrite a mutable object?

UPDATE I tried running the following code:

-(void)immutable
{
    NSString *myString1 = @"Hello!";
    NSString *myString2 = myString1;

    NSLog(@"myString1 address: %p", &myString1); //Prints 0xbfffdb30
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c

    myString2 = @"Good bye!";
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c

    NSMutableString *myMutableString = [NSMutableString stringWithString:@"Hello"];
    NSString *myString3 = myMutableString;

    NSLog(@"myMutableString address: %p", &myMutableString); //Prints 0xbfffdb28
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24

    [myMutableString setString:@"Hello World"];
    NSLog(@"myString3: %@", myString3); //Prints Hello World

    myString3 = myString1;
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24

    [myMutableString setString:@"Nothing to do"];
    NSLog(@"myString3: %@", myString3); //Prints Hello!
}

I am not surprised that the address of myString1 and myString2 are different, since both are immutable objects. But even after assigning a different string to myString2, it is still pointing to the same address as before. Shouldn't it change?

But in the case of myMutableString and myString3, they still have different addresses even though any change in myMutableString will be reflected in myString3. After I assign myString1 to myString3 the address myString3 is pointing doesn't change, but then it's no longer related with myMutableString, since every change I make to it will no longer be reflected in myString3. What is causing myString3 and myMutableString be linked in the first place?

Was it helpful?

Solution

When you write foo = @"Hello World!";, foo was pointing to an NSString object that has the data "Hello World!", let's say that this object resides at address 10.

When you write foo = @"Hello everybody!", foo now points to a new object that has the data "Hello everybody!", let's say that this object resides at address 50. The first object wasn't modified at all, you just made foo point to another object at another address.

If those strings were mutable, you could modify the content,

NSMutableString *foo = @"Hello World!".mutableCopy; //LEt's say, it's @ adress 10
[foo appendString:@"How is it going?"]; // IT's still @ adress 10, but with new content.

foo now points to an object at address 10, that has modified content "Hello World!How is it going?".

In the first case, you couldn't modify NSString because it doesn't give you any methods to change the data at that address. That's immutability. NSMutableString on the other hand gives you that ability, by methods like appendString: and appendString:. This way you can change the contents of the object at the same address without having to create a new object to make those changes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top