iOS技术点

iOS对象数组的深copy

2017-12-25  本文已影响0人  xinmai

最近有个需求需要copy数组对象才发现之前一直不太了解深浅copy就随手写了个小demo研究下。

1,NSObject中的copy和mutableCopy方法

NSString *str = @"aaaa";

NSString *copyStr = [str copy];

NSString *mutableCopyStr = [str mutableCopy];

NSLog(@"str = %p, copy = %p, mutableCopy = %p",str,copyStr,mutableCopyStr);

打印结果:str = 0x10abea068, copy = 0x10abea068, mutableCopy = 0x60400025ca70

对于NSString对象来说copy方法并没有实现深copy。( str对象和copy指向同一地址)

mutableCopy方法实现了深copy。

NSMutableString *str1 = [[NSMutableString alloc]initWithString:@"aaaa"];

NSMutableString *copy1 = [str1 copy];

NSMutableString *mutableCopy1 = [str1 mutableCopy];

NSLog(@"str1 = %p , copy = %p , mutableCopy = %p",str1,copy1,mutableCopy1);
打印结果:   str1 = 0x60400025cf20 , copy = 0xa000000616161614 , mutableCopy = 0x60400025cce0

 [str1 appendString:@"bbbb"];
  NSLog(@"str1 = %@ , copy = %@ , mutableCopy = %@",str1, copy1,mutableCopy1);
打印结果:    str1 = aaaabbbb , copy = aaaa , mutableCopy = aaaa

对于NSMutableString对象来说mutableCopy和copy都实现了深copy。

经测试NSArray,NSDictionary等对象和NSString一样copy浅copy mutableCopy深copy

NSMutableArray,NSMutableDictionary等可变对象和NSMutableString一样copy和mutableCopy实现了深copy

自定义Person类实现NSCopying协议

@interface Person : NSObject<NSCopying>
@property (strong, nonatomic) NSString *name;
@end

#import "Person.h"

@implementation Person

- (id)copyWithZone:(NSZone *)zone {

Person *p = [Person new];

p.name = _name;

return p;

}

@end

Person *p = [[Person alloc]init];

p.name= @"kk";

Person *p1 = [p copy];

p1.name = @"kkoo";

NSLog(@"p name = %@ , p1 name = %@", p.name,p1.name);

打印结果p name = kk , p1 name = kkoo

通过copy或者mutableCopy可以实现深copy

2,深copy对象数组

 Person *p = [[Person alloc]init];
 p.name= @"kk";

NSArray *arr = @[p];

NSArray *arr1 = [arr mutableCopy];

NSLog(@"arr = %p, arr1 = %p", arr, arr1);

打印结果:arr = 0x604000009cf0, arr1 = 0x6040004579d0。  深copy数组

Person *p_arr = arr[0];

Person *p_arr1 = arr1[0];

NSLog(@"p_arr = %p, p_arr1 = %p",p_arr,p_arr1);

打印结果:p_arr = 0x60000001f6d0, arr1 = 0x60000001f6d0

数组里面对象并没有得到深copy

此时大致能想到两种方法真正实现对象数组的深copy

第一种,重新声明一个数组对象,遍历之前的数组对象调用Person的copy方法插入新数组

NSMutableArray *arr3 = [NSMutableArray array];

for (Person *person in arr) {

Person *tmpPerson = [person copy];

[arr3 addObject:tmpPerson];

}//或者不用copy方法直接初始化新的Person对象插进数组

得到arr3实现数组对象arr的深copy

第二种,利用归档的方法重新获得数组

在Person 类中实现NSCoding协议

- (void)encodeWithCoder:(NSCoder *)aCoder {

[aCoder encodeObject:_name forKey:@"name"];

}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

self = [super init];

if (self) {

_name = [aDecoder decodeObjectForKey:@"name"];

}

return self;

}

NSArray *arr4 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:arr]];

得到arr4实现数组对象arr的深copy

上一篇 下一篇

猜你喜欢

热点阅读