Reputation: 3849
I know, this is basic stuff. But I get confused about this all the time.
So let's say I have a class called HolderClass with an NSString property called changeMe.
I have another class called PassedToClass, and it has a method that takes an instance of HolderClass as a parameter, and inside that method it uses that instance of HolderClass to set a property called holderInsideOtherClass.
I'm going to pass an instance of holderClass into an instance of PassedToClass like so:
HolderClass *demonstrationHolder= [HolderClass new];
PassedToClass *passToMe = [PassedToClass new];
demonstrationHolder.changeMe = @"FirstString";
[passToMe arbitraryMethodThatTakesAHolderClass: demonstrationHolder];
Now, after this is done, I can check the value of changeMe inside both classes:
NSLog (@"%@", demonstrationHolder.changeMe);
NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);
And both of those should print out "FirstString".
But now, what happens if I do this:
[demonstrationHolder.changeMe = @"SecondString"];
NSLog (@"%@", demonstrationHolder.changeMe);
NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);
I know I should know this already, but can anybody help?
Upvotes: 0
Views: 30
Reputation: 26863
HolderClass *demonstrationHolder= [HolderClass new];
When this line of code executes, the memory is allocated for one instance of HolderClass
, and you are given a pointer (a HolderClass *
) to that instance, which you assign to demonstrationHolder
.
Once you have your pointer, you're assigning it to a member within the passToMe
instance:
[passToMe arbitraryMethodThatTakesAHolderClass: demonstrationHolder];
This is still the same pointer value represented by demonstrationHolder
; all it is is a memory location where the real instance of HolderClass
exists.
[demonstrationHolder.changeMe = @"SecondString"];
Because both pointers (demonstrationHolder
and passToMe.holderInsideOtherClass
) point to the same instance, when you use either of them to access the instance of HolderClass
, you're modifying the same object in memory. Therefore:
NSLog (@"%@", demonstrationHolder.changeMe);
NSLog (@"%@", passToMe.holderInsideOtherClass.changeMe);
Both of these lines will log "SecondString"
.
Upvotes: 0
Reputation: 73946
Variables that hold objects are merely pointers (memory addresses). When you pass them around or assign them to other variables, you're still referencing the exact same object at the exact same memory location.
So when you pass demonstrationHolder
into passToMe
, passToMe
simply gets a reference to the original object. If you change that particular object anywhere, those changes will show up for every piece of code that holds a reference to that particular object. It's the same object.
When dealing with objects that can change in this way ("mutable" objects), it is common to define properties as being copy
rather than assign
/retain
/strong
. When this is the case, and you assign an object to that property, instead of it simply storing a reference, a new object is created that is a copy of the original object, and a reference to the new object is stored instead. This means that any future changes to the original object will not affect the new copy.
Upvotes: 3