1.NSArray 用copy修饰。
@property (nonatomic, copy) NSArray *arrayBooks;
NSMutableArray *mutableArray = [NSMutableArray array];
for (NSInteger i = 0; i< 3; i++) {
Book *book = [Book new];
book.pages = 200;
book.auther = @"李白";
[mutableArray addObject:book];
}
NSLog(@" 指针地址为:%p books: %@",mutableArray,mutableArray);
self.arrayBooks = mutableArray;
NSLog(@"self 指针地址为:%p self books: %@",self.arrayBooks,self.arrayBooks);
(Book 为只有pages(NSIntege)和 auther(NSString)属性的Model类)
打印结果如下:
2017-08-11 14:10:55.588 ArrayCopyTest[19240:42219127] 指针地址为:0x60000004ac80 books: (
"",
"",
""
)
2017-08-11 14:10:55.589 ArrayCopyTest[19240:42219127] self指针地址为:0x60000004ace0 self books: (
"",
"",
""
)
self.arrayBooks与mutableArray 为两块不同的内存地址。但容器里的对象指针。是指向了相同的对象。
当我们修改mutableArray里的一个对象时:
Book *lastBook = mutableArray.lastObject;
lastBook.pages = 300;
lastBook.auther = @"杜甫";
NSLog(@" 指针地址为:%p books: %@",mutableArray,mutableArray);
Book *selfarrayLastBook = self.arrayBooks.lastObject;
NSLog(@"self last Book 指针地址为:%p ",selfarrayLastBook);
发现。self array里同一对象,指针依然与mutablArray里对象指向同一地址,对象的对应属性也同样发生改变。
2017-08-11 15:09:59.829 ArrayCopyTest[20179:42512532] 指针地址为:0x60800004f000 books: (
"",
"",
""
)
2017-08-11 15:10:01.291 ArrayCopyTest[20179:42512532] self last Book指针地址为:0x608000036840
故:Array使用Copy修改,相对于Array对象是深拷贝。对于array里的对象,只是拷贝了对象指针地址。故对于容器里的对象只是浅拷贝。
2.Array的 mutableCopy
NSArray *copyArray = [mutableArray mutableCopy];
NSLog(@"copyArray 指针地址为:%p copyArray: %@",copyArray,copyArray);
2017-08-11 16:29:34.775 ArrayCopyTest[20179:42512532] copyArray指针地址为:0x60800004ef10 copyArray: (
"",
"",
""
)
而上面mutableArray的地址是0x60800004f000。copyArray也是重新分配的空间,但copyArray里内容依然是浅拷贝。
3.NSCopying协议
我们给book实现 copyWithZone协议方法。
- (id)copyWithZone:(nullable NSZone *)zone {
Book *bookCopy = [Book allocWithZone:zone];
bookCopy.pages = self.pages;
bookCopy.auther = self.auther;
return bookCopy;
}
就可以使用给book对象copy了。
Book *newBook = [[Book alloc] init];
newBook.pages = 500;
[mutableArray addObject:newBook];
Book *copyBook = [newBook copy];///实现copyWithZone:所以copyBook也是深拷贝
[booksArray addObject:copyBook];
booksArray加入的是copy产生的对象。所以当改变newBook,copyBook不会改变
newBook.pages = 600;
Book *booksLast = booksArray.lastObject;
NSLog(@"self last Book 指针地址为:%p ",booksLast);
booksLast.auther = @"王朔";
NSLog(@"booksArray 指针地址为:%p booksArray: %@",booksArray,booksArray);
2017-08-11 17:19:10.055 ArrayCopyTest[20179:42512532] self last Book指针地址为:0x600000035540
2017-08-11 17:19:13.506 ArrayCopyTest[20179:42512532] booksArray指针地址为:0x60000004e310 booksArray: (
"",
"",
"",
""
)
控制台结果:
地址指针不同,改变后也不影响前值。
4.使用NSKeyedUnarchive对象归档,实现array并对array里数据深copy
归档要给array容器里的对象Book实现NSCoding协议:此为Book类里实现
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:[NSNumber numberWithInteger:self.pages] forKey:NSStringFromSelector(@selector(pages))];
[aCoder encodeObject:self.auther forKey:NSStringFromSelector(@selector(auther))];
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [self init];
if (!self) {
return nil;
}
self.pages = [[aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(pages))] integerValue];
self.auther = [aDecoder decodeObjectOfClass:[NSString class] forKey:NSStringFromSelector(@selector(auther))];
return self;
}
然后通过归档得到一个Array:
///深copy! ///要实现NSCoding 协议
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:booksArray]];
NSLog(@"trueDeepCopyArray 指针地址为:%p trueDeepCopyArray: %@",trueDeepCopyArray,trueDeepCopyArray);
打印结果
2017-08-11 17:30:22.073 ArrayCopyTest[20179:42512532] trueDeepCopyArray指针地址为:0x60800004f6c0 trueDeepCopyArray: (
"",
"",
"",
""
)
trueDeepCopyArray 打印的book对象与booksArray里的。指针都不同。
5.NSDictionary
本以为dictionary 的poropety用copy修饰。应该和NSArray一样的,但发现真是too young
NSDictionary *dicTemp = @{@"chinese":newBook,@"story":booksLast};
NSMutableDictionary *copyDic = [dicTemp mutableCopy];
1) 当使用self.dicBooks = dicTemp;和self.dicBooks = [dicTemp copy];
dicBooks 的指针和dicTemp都指向同一区域。也就是说。调用self。copy时就是一赋值操作,连对dicBooks空间都没有分配。有点不理解了,why?
2) 使用mutableCopy
NSMutableDictionary *copyDic = [dicTemp mutableCopy];
NSLog(@"dicTemp 指针地址为:%p ,copyDic指针地址为:%p ",dicTemp,copyDic);
打印为:
2017-08-11 17:42:03.632 ArrayCopyTest[20179:42512532] dicTemp指针地址为:0x60000006a080 ,copyDic指针地址为:0x60800004f450
Printing description of dicTemp:
{
chinese = "";
story = "";
}
Printing description of copyDic:
{
chinese = "";
story = "";
}
也就是说mutableCopy会生成一个分配空间的mutabelDic,对于dictionary对象来说是深拷贝。对于容器里的内容依然是指针拷贝,浅拷贝。这与Arraay类似。
demo (我在这里)
个人总结,方便以后查看。如有不对欢迎指正