ios模型拷貝/傳值
阿新 • • 發佈:2019-01-11
場景:兩個介面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;
//1.取出所有的屬性
objc_property_t *propertes = class_copyPropertyList([self class], &count);
//2.遍歷的屬性
for (int i=0; i<count; i++) {
//獲取當前遍歷的屬性的名稱
const char *propertyName = property_getName(propertes[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
//利用KVC取出對應屬性的值
id value = [self valueForKey:name];
//歸檔到檔案中
[aCoder encodeObject:value forKey:name];
}
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
unsigned int count =0;
//1.取出所有的屬性
objc_property_t *propertes = class_copyPropertyList([self class], &count);
//2.遍歷所有的屬性
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.className = [decoder decodeObjectForKey:@"className"];
[self setValue:value forKey:name];
}
}
return self;
}
- 使用上如下:
1.歸檔:[NSKeyedArchiver archiveRootObject:self.leftModel toFile:@”model儲存路徑”];
2.解檔:Model * model = [NSKeyedUnarchiver unarchiveObjectWithFile:@”model儲存路徑”];