鸣谢:YYKit https://github.com/ibireme/YYKit
文件:NSObject+YYAdd.h
之前对相对复杂的对象做深拷贝都是用实现copy协议来做:
- (id)copy;
- (id)mutableCopy;
+ (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;
+ (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;
在数据结构复杂,这样做就也特别复杂,而且容易出错。
今天看到一种新的方法,而且很巧妙:
利用解档归档可以重新申请内存的原理可以做到完全的深复制!
- (id)deepCopy {
id obj = nil;
@try {
obj = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
return obj;
}
- (id)deepCopyWithArchiver:(Class)archiver unarchiver:(Class)unarchiver {
id obj = nil;
@try {
obj = [unarchiver unarchiveObjectWithData:[archiver archivedDataWithRootObject:self]];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
return obj;
}
需要注意的是,在使用解档归档的时候需要对应实现方法:
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
和
- (void)encodeWithCoder:(NSCoder *)aCoder;
由于我们项目普遍是用的的json格式,则可以统一将对应的数据模型转为json进行归档,然后接档出来的也对应的是json格式,在对此json进行格式化,转为我们需要的数据模型!
这里贴出JsonModel对应的接档归档的源码,可以参考一下:
-(instancetype)initWithCoder:(NSCoder *)decoder
{
NSString* json = [decoder decodeObjectForKey:@"json"];
JSONModelError *error = nil;
self = [self initWithString:json error:&error];
if (error) {
JMLog(@"%@",[error localizedDescription]);
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.toJSONString forKey:@"json"];
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
此处值得注意的两点是(也是难点):
1、如何将json转为对应的数据模型
2、如何将数据模型逆转为json
解决方案:可利用JsonModel
来进行“json<->数据模型”的互转