OC copy关键字

来源:互联网 发布:互联网巨头反恐数据库 编辑:程序博客网 时间:2024/05/19 13:25

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 为只有pagesNSIntege)和 auther(NSString)属性的Model类)

打印结果如下:

2017-08-11 14:10:55.588 ArrayCopyTest[19240:42219127] 指针地址为:0x60000004ac80 books: (    "<Book: 0x600000221360>",    "<Book: 0x60000003dc80>",    "<Book: 0x60000003fd80>")2017-08-11 14:10:55.589 ArrayCopyTest[19240:42219127] self指针地址为:0x60000004ace0 self books: (    "<Book: 0x600000221360>",    "<Book: 0x60000003dc80>",    "<Book: 0x60000003fd80>")

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: (    "<Book: 0x608000036660>",    "<Book: 0x608000036820>",    "<Book: 0x608000036840>")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: (    "<Book: 0x608000036660>",    "<Book: 0x608000036820>",    "<Book: 0x608000036840>")

而上面mutableArray的地址是0x60800004f000copyArray也是重新分配的空间,但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: (    "<Book: 0x608000036660>",    "<Book: 0x608000036820>",    "<Book: 0x608000036840>",    "<Book: 0x600000035540>")

控制台结果:


地址指针不同,改变后也不影响前值。

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: (    "<Book: 0x608000036ac0>",    "<Book: 0x608000036b80>",    "<Book: 0x608000036640>",    "<Book: 0x6080000368a0>")

trueDeepCopyArray 打印的book对象与booksArray里的。指针都不同。


5.NSDictionary

本以为dictionary poropetycopy修饰。应该和NSArray一样的,但发现真是too young

NSDictionary *dicTemp = @{@"chinese":newBook,@"story":booksLast};    NSMutableDictionary *copyDic = [dicTemp mutableCopy];

1) 当使用self.dicBooks = dicTemp;self.dicBooks = [dicTemp copy];

dicBooks 的指针和dicTemp都指向同一区域。也就是说。调用selfcopy时就是一赋值操作,连对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 = "<Book: 0x6000000355e0>";    story = "<Book: 0x600000035540>";}Printing description of copyDic:{    chinese = "<Book: 0x6000000355e0>";    story = "<Book: 0x600000035540>";}

也就是说mutableCopy会生成一个分配空间的mutabelDic,对于dictionary对象来说是深拷贝。对于容器里的内容依然是指针拷贝,浅拷贝。这与Arraay类似。

demo 我在这里

个人总结,方便以后查看。如有不对欢迎指正

 
原创粉丝点击