场景:两个界面A,B(Apush到B界面)同时需要引用同一个model,并修改.
问题是:在B中如果直接用一个同类型model的属性来接受A界面传过来的Model时,在B界面修改model后,A界面对应的model也会发生变化.
希望达到的目的:A,B对相同数据的model,进行引用修改彼此不影响.
由上面的场景,初步探究有以下经验,和大家分享下,不对之处,大家多多指正,谢谢!
解决方案1:实现model拷贝功能,需要model遵循NSCopying协议,主要代码和实验如下:
@interface modelCopy : NSObject<NSCopying>
@property (copy, nonatomic) NSString *name;
@end
- (id)copyWithZone:(NSZone *)zone {
modelCopy *model = [[self class] allocWithZone:zone];
model.name = [_name copy];
return model;
}
- 结果如下:可以看出model的地址已经发生变化,当然如果model中嵌套model,则嵌套的model也要对应遵循NSCopying协议以及协议方法
解决方案2.model归档,完全复制,model需要遵循NSCoding,已经实现归档与解档方法,但是如果一个model属相太多,在encode和initWithCoder中一个个写属性的对应声明,会稍微费事,下面是采用runtime机制来实现,感觉很好用,贴出来以供大家参考:
- (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int count = 0;
objc_property_t *propertes = class_copyPropertyList([self class], &count);
for (int i=0; i<count; i++) {
const char *propertyName = property_getName(propertes[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
id value = [self valueForKey:name];
[aCoder encodeObject:value forKey:name];
}
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
unsigned int count =0;
objc_property_t *propertes = class_copyPropertyList([self class], &count);
for (int i = 0; i < count; i++) {
const char *propertyName = property_getName(propertes[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
id value = [aDecoder decodeObjectForKey:name];
[self setValue:value forKey:name];
}
}
return self;
}
- 使用上如下:
1.归档:[NSKeyedArchiver archiveRootObject:self.leftModel toFile:@”model存储路径”];
2.解档:Model * model = [NSKeyedUnarchiver unarchiveObjectWithFile:@”model存储路径”];