runtime序列化與反序列化

使用簡單的數據存儲有時候須要用到 NSCoding協議 實現其 encodeWithCoder 與 initWithCoder 方法代理

通常實現的姿式是這樣的:code

 

可是這樣會有一個缺陷, 若是咱們想加一個屬性, 就要再在NSCoding代理方法里加入屬性的序列化和反序列化操做, 不然會很容易致使項目崩潰, 那麼有沒有一種方式實現NSCOding協議而又不用再修改呢, 這時就須要用到強大的runtime了:blog

這樣寫的好處是無論有多少屬性, 這兩個方法都能經過runtime獲取全部屬性存取解決, 之後再添加任何屬性都不用擔憂NSCoding協議方法會有問題啦get

// copy代碼請下拉:string

// 歸檔it

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

    unsigned int count = 0;List

    //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 setValue:value forKey:name];

        }

    }

    return self;

}

相關文章
相關標籤/搜索