iOS 数组元素的深拷贝

作者: 我是C | 来源:发表于2016-02-17 11:53 被阅读2905次
  • 需求:一个对象数组,然后想将这个数组拷贝出来一份用,修改拷贝的这份数组,保持原始数据不被改变.
  • 如果数组的元素是对象(比如是个model) 需要实现,
    <NSCopying,NSMutableCopying>
    (NSMutableArray,NSArray,NSString等实现了该协议)
  • 协议对应方法:
    - (id)copyWithZone:(nullable NSZone *)zone
    - (id)mutableCopyWithZone:(nullable NSZone *)zone
  • 举例:
实现 NSCopying,NSMutableCopying 协议
如果用NSCopying 实现:
 - (id)copyWithZone:(nullable NSZone *)zone
如果用NSMutableCopying 实现:
  - (id)mutableCopyWithZone:(nullable NSZone *)zone
Model
@interface Model : NSObject<NSCopying,NSMutableCopying>
@property (nonatomic, copy) NSString *str1;
@property (nonatomic, copy) NSString *str2;
@end 
@implementation Model
  - (id)copyWithZone:(nullable NSZone *)zone{
 Model *person = [[self class] allocWithZone:zone];
 person.str1 = [_str1 copy];
 person.str2 = [_str2 copy];
 return person;
}
  - (id)mutableCopyWithZone:(nullable NSZone *)zone{
 Model *person = [[self class] allocWithZone:zone];
 person.str1 = [_str1 copy];
 person.str2 = [_str2 copy];
 return person;
}
@end
  • 实现了协议以后,那么该对象就可以进行拷贝了,下面说说数组是怎么回事
//构造一个Model 数组
  NSMutableArray *arr = [NSMutableArray array];
  for (int i = 0; i< 3; i++) {
  Model *model = [[Model alloc] init];
  model.str1 = @"1";
  model.str2 = @"2";
  NSLog(@"数组%d:---%p",i,model);
  [arr addObject:model];
  }
那么我想拷贝数组对象,直接
NSMutableArray *arr1 = [arr mutableCopy];
是不是这样就可以了
arr内存地址:0x7f8d8b7972a0
arr1内存地址:0x7f8d8b796fe0
显然是不一样的,那么你会说这样就可以了,其实你想多了,断点后看两个数组的元素的地址改变了没有:
结果:po arr
<__NSArrayM 0x7f8d8b7972a0>(
<Model: 0x7f8d8b78f110>,
<Model: 0x7f8d8b52b470>,
<Model: 0x7f8d8b408830>
)
po arr1
<__NSArrayM 0x7f8d8b796fe0>(
<Model: 0x7f8d8b78f110>,
<Model: 0x7f8d8b52b470>,
<Model: 0x7f8d8b408830>
)
  • 元素对象是一样的,地址完全一样,所以说数组的指针变了,但是数组元素是没有变的,该如何解决呢?先上一段代码.
  NSMutableArray *arr = [NSMutableArray array];
  for (int i = 0; i< 3; i++) {
  Model *model = [[Model alloc] init];
  model.str1 = @"1";
  model.str2 = @"2";
  NSLog(@"数组%d:---%p",i,model);
  [arr addObject:model];
  }
  NSMutableArray *arr1 = [NSMutableArray array];
  for (Model *model in arr) {
  [arr1 addObject:[model copy]];//这里的copy,就是将arr数组里的每一个对象拷贝一份.
//所以Model对象实现- (id)copyWithZone:(nullable NSZone *)zone方法
  }
  • 解决方法

  • 目前我想到的是遍历数组 将数组元素深拷贝出来添加到另一个数组里.如果有同学想到了其他更好的方法希望能告知我,谢谢.

相关文章

  • 关于OC中数组的深、浅拷贝的小总结

    简而言之:数组的深拷贝,仅仅只是拷贝数组的内容,数组内元素的地址不会变,如果想要数组内的对象元素也深拷贝,则数组内...

  • iOS 数组元素的深拷贝

    需求:一个对象数组,然后想将这个数组拷贝出来一份用,修改拷贝的这份数组,保持原始数据不被改变. 如果数组的元素是对...

  • iOS 数组元素的深拷贝

    碰到同样的需求,数组元素不能深拷贝的解决方法https://www.jianshu.com/p/976070ac4949

  • iOS 数组深复制 NSMutableCopy

    实现模型数组深拷贝的方法1、最笨的方法就是通过遍历逐个拷贝元素 2、也有人使用归档解档实现数组内部元素拷贝 3、这...

  • 关于几个拷贝的问题

    数组浅拷贝 数组深拷贝 复合数组深拷贝

  • JS-数组中元素深拷贝

    数组A中数据放入数组B,修改B中的元素后,A中元素也改变了,是因为使用了浅拷贝。若使用深拷贝复制数组,便可解决此问...

  • iOS 浅拷贝、深拷贝、数组深拷贝

    需求:一个对象数组,然后想将这个数组拷贝出来一份用,修改拷贝的这份数组,保持原始数据不被改变. 我自己的理解: c...

  • iOS 浅拷贝、深拷贝、数组深拷贝

    需求:一个对象数组,然后想将这个数组拷贝出来一份用,修改拷贝的这份数组,保持原始数据不被改变.我自己的理解: co...

  • 11_聊一聊js中实现数组拷贝的常用方法

    一、数组赋值 1、要点 用数组直接赋值的方式实现数组的拷贝,改变拷贝后的数组的元素,被拷贝的数组的元素也会发生改变...

  • 深拷贝和浅拷贝

    1: iOS开发 深拷贝与浅拷贝 2: iOS 浅谈:深.浅拷贝与copy.strong 3: iOS开发——深...

网友评论

  • Juice007:博主,你实现的copyWithZone方法里面allocWithZone之后不init也能用?
    我是C:可以啊,你跑代码试试
  • SAW_:我的model里面有一堆的参数,去写copyWithZone跟mutableCopyWithZone的话很蛋疼,有么有快速的方法:smiley:
    三三哥:Runtime 然后KVC赋值
    BaseModel *model = [[[self class] allocWithZone:zone] init];
    [[[self class] getPropertyNameList:[model class] ] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [model setValue:[self valueForKey:obj] forKey:obj];
    }];

    - (NSArray*)getPropertyNameList:(Class)cls {
    NSMutableArray *propertyNameListArray = [NSMutableArray array];
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList(cls, &count);
    for (NSInteger i = 0 ; i < count; i ++) {
    const char *propertyCharName = property_getName(properties[i]);//c的字符串
    NSString *propertyOCName = [NSString stringWithFormat:@"%s",propertyCharName];//转化成oc 字符串
    [propertyNameListArray addObject:propertyOCName];
    }
    NSArray *dataArray = [NSArray arrayWithArray:propertyNameListArray];
    return dataArray;
    }
    SAW_:@我是C :disappointed_relieved: 好吧
    我是C:runtime
  • 爱吃鱼的:[[NSMutableArray alloc] initWithArray:arr1 copyItems:YES] 试试这个
    追逐你的影子:@Kevin20481 对啊 copy模型中又嵌套了数组模型,不知道怎么弄了
    Vincent20481:@TTanys 模型中有数组,copy 模型 怎么样才能改变其中数组中模型地址
    TTanys:是的,实现了model的NSCopying和NSMutableCopying后直接这个方法[[NSMutableArray alloc] initWithArray:arr1 copyItems:YES] 去copy数组就可以了,这样数组里面的model也同样copy了。
  • xxttw:我有个需求和你一毛一样. 最后我也是遍历copy 添加到数组中.
    我是C:@Unc1eWang 好像都这么弄

本文标题:iOS 数组元素的深拷贝

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