I am trying to understand copying objects from one NSMutableArray to another. Consider the following 2 scenarios: 1 - copying original to clone where changes in the clone will affect the original. 2 - copying original to clone where the changes in the close will NOT affect the original.
First, I am trying to produce scenario #1 first with the following code. From what I understand, when copying array not using 'mutablecopy', the clone array will just hold the pointer to the same string objects in the original. So if I were to change the first element of the clone to a different object, the first element of the original would change too right? ... but that's not the result I am getting. Why?
Matter of fact, when I use mutablecopy
[self.cloneArray addObject:[[self.originalArray objectAtIndex:i] mutableCopy]];
I get the same result. I am confused.
ArrayClass.h
@interface ArrayClass : NSObject {
NSMutableArray *_originalArray;
NSMutableArray *_cloneArray;
}
@property (nonatomic, retain) NSMutableArray *originalArray;
@property (nonatomic, retain) NSMutableArray *cloneArray;
ArrayClass.m
@synthesize originalArray = _originalArray;
@synthesize cloneArray = _cloneArray;
_originalArray = [[NSMutableArray alloc] initWithObjects: @"one", @"two", @"three", @"four", @"five", nil];
_cloneArray = [[NSMutableArray alloc] initWithCapacity:[self.originalArray count]];
for (int i=0; i<5; i++) {
[self.cloneArray addObject:[self.originalArray objectAtIndex:i]];
}
开发者_C百科
// make change to the first element of the clone array
[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];
for (int n=0; n<5; n++) {
NSLog(@"Original:%@ --- Clone:%@", [self.originalArray objectAtIndex:n], [self.cloneArray objectAtIndex:n]);
}
...
2011-03-27 03:23:16.637 StringTest[1751:207] Original:one --- Clone:blah
2011-03-27 03:23:16.638 StringTest[1751:207] Original:two --- Clone:two
2011-03-27 03:23:16.639 StringTest[1751:207] Original:three --- Clone:three
2011-03-27 03:23:16.642 StringTest[1751:207] Original:four --- Clone:four
2011-03-27 03:23:16.643 StringTest[1751:207] Original:five --- Clone:five
You are thinking about this way too hard.
In Objective-C, you have references to objects. An NSString *foo;
simply defines a variable foo
that refers to an NSString
. If you say NSString *bar = foo;
, then bar
will have a reference to whatever object foo
was referring to. No more, no less.
An NSArray
is just a collection of object references. So, if you say:
NSArray *b = [NSArray arrayWithArray: a];
You are creating an array b
that contains all of the same references to the exact same set of objects as a
. If you modify an object referred to by a
, that'll be the exact same object in b
and the modification will be reflected.
When you copy an object, you are creating a new object that has the identical internal state as the original. I.e. when you say NSMutableString *foo = [barString mutableCopy];
, then foo
is a reference to a new string; a different one than barString
.
So... when creating a new array, the question is do you want the array to contain the exact same contents as the original array or do you want it to contain a new set of objects that you can modify?
You have a misunderstanding of what's going on. The replaceObjectAtIndex:withObject:
call isn't modifying objects in the array, it's modifying the array itself. After this line:
[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];
you've replaced the object in your clone array, but you haven't changed the original array at all. If you actually modified the NSString
object you put in the arrays, you might be able to get the behaviour you were expecting. You won't be able to do it with the objects you've put into the original array in your example, though, since they're immutable string objects. If you stuck mutable strings in there, used the same loop to 'clone' your array, and then did something along the lines of:
[[self.cloneArray objectAtIndex:0] appendString:@"some junk to append"];
you would actually modify the string object at index 0. Since both arrays still contain that same object, you'd get the 'modify original array by changing the objects in the clone array' behaviour.
精彩评论