美文网首页
iOS 数组深拷贝-mutableCopy?

iOS 数组深拷贝-mutableCopy?

作者: 哦小小树 | 来源:发表于2020-04-26 21:31 被阅读0次

0x01 场景

现在需要将一个数组中的元素进行排序,然后对对象进行标记,但是又不能影响到原来的数据,那么我们就需要制造一个备份。

要求:这个备份,不仅数组跟原来不同,数组中的内容也不能与原来一样

准备工作:


@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end

NSMutableArray *tmpArr = @[].mutableCopy;
for (int i = 0; i<5; i++) {
    Person *p = [Person new];
    p.name = @(i).stringValue;
    p.age = i;
    [tmpArr addObject:p];
}

0x01 [array copy]

NSArray *tmp2 = [tmpArr copy];

效果图对比:

WeChat2e5d6b6726186c947a9470b90dde8343.png

与我们设想并不冲突,通过copy确实生成一个不可变的Array对象。

但是我们需要时可变的数组,里面的对象还要与原来的对象不是同一个,那尝试下mutableCopy


0x02 [array mutableCopy]

NSMutableArray *tmp2 = [tmpArr mutableCopy];
WeChat381d16df9085c8b8a5a3aa72407edf76.png

虽然生成了一个可变数组,但是我们的可变数组中的内容依旧是原来内容,如果修改了依然会导致源数据发生改变。

所以这种方案依然不可选。


0x03 怎样实现数组深拷贝

该怎么实现数组深拷贝呢?查看系统API方法,可以看到:

// NSArray.h
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

如果flagYES,那么就会去调用array中对象的copy方法。
如果flagNO,只是把数组中的对象做一次retain操作,再赋值给新对象。

通过上面描述可以了解到,如果flag我们传入YES,然后重写Person类的copy方法,那就可以自己实现深拷贝。

代码如下:

// .h
@interface Person : NSObject <NSCopying>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end


// .m

- (id)copyWithZone:(nullable NSZone *)zone {
    Person *p = [Person new];
    p.name = self.name;
    p.age = self.age;
    return p;
}
// 调用
NSMutableArray *tmp2 = [[NSMutableArray alloc] initWithArray:tmpArr copyItems:YES];
WeChat66829fb775b5e74dc59d69ff6190da92.png

得到结果为,tmp2是个可变数组,并且里面的对象做了深拷贝。


0x04 总结

copy/mutableCopy只能让调用此方法的对象创建一个不可变/可变的对象,但是并能将其影响到里面的内容。

如果需要影响其内容,应该用某种机制,让内部的对象自己调用自己的copy/mutableCopy方法。

相关文章

网友评论

      本文标题:iOS 数组深拷贝-mutableCopy?

      本文链接:https://www.haomeiwen.com/subject/tlqswhtx.html