You are looking at three different variables pointing to the same object, so of course when you display the output, you'll see the same object each time.
The retain
vs assign
are types of memory qualifiers, but don't affect what the the underlying object is. Specifically, they merely affect the retainCount
of the underlying object.
Let's look at your three lines of code:
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:@"1",@"2",@"3", nil];
That creates an object with a retain count of +1.
NSMutableArray *arr2 = [arr1 retain];
This increases the retain count of that object to +2, and you have another variable that points at that same object.
NSMutableArray *arr3 = arr1; //Assign
This doesn't increase the retain count any further, and you now have a third variable that points to the same object.
The fundamental game of "reference counting" memory management is to ensure that:
an object that is being used has a positive retain count (so that it isn't deallocated while you are still using it) ... failure to do this properly can result in an object being deallocated prematurely, possibly leaving you with dangling references; and
an object with which you have no further use has its retainCount
reduced to zero, so that when the autorelease pool is drained, the object will be deallocated ... failure to decrement the counter at the right places can result in an object being leaked.
As you can imagine, this results in a fairly fragile process, where we must make sure that we increment and decrement our retain counts with retain
, release
and autorelease
in the right places. Xcode's "static analyzer" ("Analyzer" option on Xcode's "Product" menu or by pressing shift+command+B) does an excellent job of looking at our code and identifying whether we've done this properly. If you're writing manual reference counting code, this tool is indispensable.
But, the beauty of "automatic reference counting" is that we leave this silly world of incrementing and decrementing the object retainCount
values behind us. We shift to a world where we can focus on the "object graph", what sorts of references we need at certain places in our code, and the compiler takes care of incrementing and decrementing the retainCount
for us.