包含有对象类型的数组。无论可变还是不可变,通过copy,mutableCopy都不能将数组内的model完全copy一份,虽然得到的数组是新的,但数组中model的指针指向的还是之前的model。此时,如果改变了数组中model的值,原数组会受到影响。
Person * a = [Person new];
a.name = @"a";
a.gender = @"male";
Person * b = [Person new];
b.name = @"b";
b.gender =@"female";
NSMutableArray *mutA = [NSMutableArray arrayWithObjects:a,b, nil];
NSMutableArray *mutB = [mutA mutableCopy];
Person *c = mutB.firstObject;
c.name = @"c";
c.gender = @"female";
exOne.jpg
如果对象是单层的(没有嵌套的模型),此时,model遵循NSCopying,NSMutableCopying协议,实现copyWithZone和mutableCopyWithZone方法。
- (id)copyWithZone:(NSZone *)zone{
Person *person = [[Person allocWithZone:zone] init];
person.name = self.name;
person.gender = self.gender;
return person;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
Person *person = [[Person allocWithZone:zone] init];
person.name = self.name;
person.gender = self.gender;
return person;
}
Array通过 initWithArray:copyItems: 方法可以得到一个完全拷贝过的数组(数组内的model也是全新的model)。
NSMutableArray *mutB = [[NSMutableArray alloc] initWithArray:mutA copyItems:YES];
exTwo.jpg
但是!!
如果数组内的model有嵌套,这个方法就不行了。
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) Gender *gender;
@end
Person * a = [Person new];
a.name = @"a";
Gender *agender = [Gender new];
agender.title = @"male";
a.gender = agender;
Person * b = [Person new];
b.name = @"b";
Gender *bgender = [Gender new];
bgender.title =@"female";
b.gender = bgender;
NSMutableArray *mutA = [NSMutableArray arrayWithObjects:a,b, nil];
NSMutableArray *mutB = [[NSMutableArray alloc] initWithArray:mutA copyItems:YES];
Person *c = mutB.firstObject;
c.name = @"c";
c.gender.title = @"female";
exThree.jpg
可以看出,改动B数组中的firstObject,A中的name没有跟着改变,但A中的gender发生了变化。
接下来再试一下,gender类也遵循NSCopying,NSMutableCopying协议。看下是什么效果。
- (id)copyWithZone:(NSZone *)zone{
Gender *gender = [[Gender allocWithZone:zone] init];
gender.title = self.title;
return gender;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
Gender *gender = [[Gender allocWithZone:zone] init];
gender.title = self.title;
return gender;
}
exFour.jpg
如上图所示,依然不能满足要求。
归档接归档。
将A数组序列化为一个Data,再将Data解归档为一个新的数组。此时的数组就是一个全新的数组。
person和gender类都需要遵循NSCoding协议,实现initWithCoder 和 encodeWithCoder方法。
exSix.jpg
再试一次, bingo!
exFive.jpg
网友评论