In Objective-C the only way you can get to an Object is through a pointer. So:
Code:
NSArray *myArrayOne = [NSArray arrayWithObjects: @"One",@"Two",@"Three",nil];
NSArray *myArrayTwo = myArrayOne;
myArrayOne = nil;
Results in an NSArray Object being created "out there", and a pointer to it being returned and assigned to the variable myArrayOne, whose type is NSArray *. The second line will take the pointer and store it to the variable myArrayTwo. There is only one NSArray Object in play "out there", but now two things are storing the memory address where it is stored. The third line will set myArrayOne to point to nil, the "nothing pointer". myArrayTwo still holds the address to the NSArray Object that's "out there". You could set it to nil, too, but you'd no longer have any way to get to your NSArray Object. It would still sit there happily, storing its Objects, with a dumb grin on its face. Since you don't own the Object created with arrayWithObjects, when the autorelease pool gets drained it will go away.
For all intents and purposes you need to think of pointers as your way to get to an Object, *not* the Object itself. You can make copies of the pointer, and act on the Object through both pointers, but it's the same Object out there that's being affected.
In your example:
array1 = array2;
Assuming these are pointers to some Object, it just stores the pointer that array2 was holding in array1. The Object is unaffected.
array1 = array2;
array2 = nil;
array1 will have the pointer to the Object, array2 will be nil and point to no Object anymore. The Object itself will remain unaffected.
Code:
NSArray *array1 = [NSMutableArray arrayWithArray: array2];
This doesn't leak any memory at all. You simply have two arrays. array1 will be an autoreleased Object, so unless you retain it, then fail to release it, no leaking will go on at all. If you owned the Object pointed to by array2, failed to release it, then set array2 to nil with no other way to get to that Object, you might have problems.
Code:
NSArray *array2 = [[NSArray alloc] initWithObjects: @"One",@"Two",@"Three",nil];
NSArray *array1 = [NSMutableArray arrayWithArray: array2]; //I left this as a pass to NSMutableArray because that's what you had
array2 = nil;
*This* leaks. array2 was pointing to an NSArray that you had ownership of, then before releasing it, you lost your only pointer. Now you're in trouble.
As a separate note, arrayWithArray passed to NSMutableArray will return a pointer to an NSArray, NOT an NSMutableArray. If you have an NSArray and you want a mutable version you can use setArray: or addObjectsFromArray:.
Code:
NSArray *array2 = [[NSArray alloc] initWithObjects: @"One",@"Two",@"Three",nil];
NSMutableArray *array1 = [NSMutableArray arrayWithCapacity:[array2 count]];
[array1 addObjectsFromArray: array2];
[array2 release];
array2 = nil;
This is a contrived example, but this will get you an NSArray you own, then get a mutable copy and assign the pointer to array1, then relinquish ownership of the Object pointed to by array2, then set array2 to nil.
-Lee