1. 程式人生 > >ios模型拷貝/傳值

ios模型拷貝/傳值

場景:兩個介面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儲存路徑”];