OC copy关键字

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 我在这里

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













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值