利用runtime 實現自動化歸檔

1.類的頭文件遵照<NSCoding>數組

@interface StudentModel : NSObject<NSCoding>

2.經過運行時,獲取類中的全部成員屬性,這裏用到了運行時的方法spa

// Ivar:成員屬性的意思
// 第一個參數:表示獲取哪一個類中的成員屬性
// 第二個參數:表示這個類有多少成員屬性,傳入一個Int變量地址,會自動給這個變量賦值
// 返回值Ivar *:指的是一個ivar數組,會把全部成員屬性放在一個數組中,經過返回的數組就能所有獲取到。
OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

因而咱們須要寫一個方法,來返回一個數組類中的全部屬性名稱code

// 返回self的全部對象名稱
+ (NSArray *)propertyOfSelf{
    unsigned int count;
    
    // 1. 得到類中的全部成員變量
    Ivar *ivarList = class_copyIvarList(self, &count);
    
    NSMutableArray *properNames =[NSMutableArray array];
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        
        // 2.得到成員屬性名
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        // 3.除去下劃線,從第一個角標開始截取
        NSString *key = [name substringFromIndex:1];
        
        [properNames addObject:key];
    }
    
    return [properNames copy];
}

3.在這裏,咱們已經獲取到類中的全部屬性的名稱,接着咱們須要在encodeWithCoder對屬性名稱和屬性的值進行歸檔操做,在這裏咱們遇到了一個問題,如何把屬性名稱和屬性的值對應起來呢。orm

在這裏咱們須要知道NSStringFromSelector(方法名)返回的是一個SEL變量指向方法名中的方法對象

咱們注意到每一個屬性都有兩個共同的方法那就是set方法和get方法,那麼咱們只須要經過屬性名字,建立屬性名指向的方法也就是get方法,就能獲取到屬性名對應的值。繼承

// 歸檔
- (void)encodeWithCoder:(NSCoder *)enCoder{
    // 取得全部成員變量名
    NSArray *properNames = [[self class] propertyOfSelf];
    
    for (NSString *propertyName in properNames) {
        // 建立指向get方法
        SEL getSel = NSSelectorFromString(propertyName);
        // 對每個屬性實現歸檔
        [enCoder encodeObject:[self performSelector:getSel] forKey:propertyName];
    }
}

4.接下來,咱們須要對類實現解檔方法。這裏咱們遇到第二個問題,如何對屬性名的屬性進行賦值呢?這裏咱們須要用到屬性的set方法,利用屬性名,拼接出一個set方法的字符串,並建立一個指向屬性set方法的SEL變量,而且利用performSelector實現賦值。ci

// 解檔
- (id)initWithCoder:(NSCoder *)aDecoder{
    // 取得全部成員變量名
    NSArray *properNames = [[self class] propertyOfSelf];
    
    for (NSString *propertyName in properNames) {
        // 建立指向屬性的set方法
        // 1.獲取屬性名的第一個字符,變爲大寫字母
        NSString *firstCharater = [propertyName substringToIndex:1].uppercaseString;
        // 2.替換掉屬性名的第一個字符爲大寫字符,並拼接出set方法的方法名
        NSString *setPropertyName = [NSString stringWithFormat:@"set%@%@:",firstCharater,[propertyName substringFromIndex:1]];
        SEL setSel = NSSelectorFromString(setPropertyName);
        [self performSelector:setSel withObject:[aDecoder decodeObjectForKey:propertyName]];
    }
    return  self;
}

就這樣,咱們實現了對一個類實現自動歸檔的類,下次須要建立一個Model類時,只要繼承自咱們編寫的這個類,就能實現自動歸檔啦。unicode

相關文章
相關標籤/搜索