Why do the variables behave so strange?
-
03-07-2019 - |
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" ??
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:
- Take the address that's in the
str2
variable and put the same address in thetest
variable. - Take the address that's in the
str1
variable and put the same address in thestr2
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.