Question

I thought an variable in objective-c is just a reference to an object somewhere in memory. So for my understanding, the result must have been "one", because at the end i assign the object's memory address of str1 to str2, and previously I had assignend the memory adress of str2 to test.

NSString *str1 = [NSString stringWithCString:"one"];
NSString *str2 = [NSString stringWithCString:"two"];

test = str2; // test is an instance variable. I use no getter/setter here! just for testing!
str2 = str1;
NSLog(test); // = "two" ??
Was it helpful?

Solution

This is how pointers work. The result you see is normal and correct.

Let's list all of your variables and what strings they point to in memory as they are declared:

str1 -> "One"
str2 -> "Two"

Then, you execute some assignment instructions:

test = str2;

This assigns the value of the pointer str2 to test. So the pointers are

str1 -> "One"
str2 -> "Two"
test -> "Two"

Then

str2 = str1;

Assigns the value of the pointer str1 to str2. Now the pointers are

str1 -> "One"
str2 -> "One"
test -> "Two"

Then you print test, which is pointing to what str2 was pointing to originally, which is "Two".

I think you think that since you assigned str2 to the value of str1, and test to the value of str2, that the value of str1 somehow cascades into test. This is not the case. Once test's value is assigned, the information regarding where that value came from is lost. If you want test's value to be the same as str1's, you have you reverse the order of your assignment operations:

str2 = str1;
test = str2;

OTHER TIPS

You have this:

test = str2; // test is an instance variable.testing!
str2 = str1;
NSLog(test); // = "two" ??

Now, let's pretend all those variables were ints.

On the first line, variable test is set to the value of variable str2. On the second line, variable str2 is set to the value of variable str1. On the third line, we print out the value of test, and it's indeed the value that str2 was when we assigned str2 to test. It really doesn't matter at all that we subsequently assigned str2 a different value.

Ok, but the variables are really pointers, you say, not ints.

No matter: think of a pointer as just a number, the address of somewhere in memory. And passing that to NSLog makes NSLog print not the value of the pointer, but the value of what the pointer points to, which is an array of char.

A variable is a container. The assignment takes whatever's on the right side and puts it also in whatever's on the left side. In other words, it copies the value from one variable to the other; in this case, those values are pointers (memory addresses).

So here's what you did:

  1. Take the address that's in the str2 variable and put the same address in the test variable.
  2. Take the address that's in the str1 variable and put the same address in the str2 variable.

Step 2 doesn't affect the test variable; your only assignment to that variable was in step 1.

Important: You're not copying what's at the address; you're copying the address itself. There's still only one “two” string, but between steps 1 and 2, the address of that object is in both str2 and test. Then, in step 2, you replace the address in str2 with the address of the “one” string, which also exists in str1, leaving test as the only variable that still holds the address of the “two” string.

BTW, stringWithCString: is deprecated. Use stringWithUTF8String: or stringWithCString:encoding: instead.

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