自動解析複雜類的屬性 實現歸檔或者進行序列化 反序列話的時候爲每個屬性添加序列化方法的繁瑣

最近學習了歸檔與序列化的操做,在進行操做的時候須要爲每個類寫上歸檔以及反歸檔相關的操做  但屬性較多時這是一項費力不討好的事情  遂本身寫了個工具類,可以實現自動根據屬性個數進行自動序列反序列化操做java

主要運用了ios裏runtime的方法與屬性  其實在這裏是和java的反射機制是同樣的。ios

代碼總共分爲了兩種
工具

    1.利用分類的方式實現 只須要拷貝分類進入工程  不須要進行其餘任何操做  由於分類會對全部的model起做用  因此還有第二種方式供參考學習

    2.須要將NSObject繼承改成ZJAutoCoding繼承code


代碼以下,恭敬敬上~~~繼承

//
//  NSObject+ZJAutoCoding.h
//
//  Created by Jason_Msbaby on 15/10/13.
//  Copyright © 2015年 張傑. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSObject (ZJAutoCoding)

@end






//
//  NSObject+ZJAutoCoding.m
//
//  Created by Jason_Msbaby on 15/10/13.
//  Copyright © 2015年 張傑. All rights reserved.
//

#import "NSObject+ZJAutoCoding.h"
#import <objc/runtime.h>
@implementation NSObject (ZJAutoCoding)


- (instancetype)initWithCoder:(NSCoder *)coder
{
    //獲取全部屬性
    unsigned int count = 0;
    objc_property_t *pros = class_copyPropertyList(self.class, &count);
    //遍歷屬性
    for (int i = 0; i < count; i++) {
        objc_property_t pro = pros[i];
        //當前屬性對應的名
        NSString *proName = [NSString stringWithUTF8String:property_getName(pro)];
        unsigned int c = 0;
        //獲取全部特徵
        objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c);
        //遍歷全部特徵
        for (int j = 0; j < c; j++ ) {
            objc_property_attribute_t attr = attrs[j];
            //這裏的V指的是知道屬性對應的成員變量的名稱 例如name屬性  在這裏的特徵值則爲 V:_name 咱們須要的是_name
            if (strcmp(attr.name, "V") == 0) {
                //而後咱們須要獲取實例進行賦值操做
                Ivar ivar = class_getInstanceVariable(self.class, attr.value);
                object_setIvar(self, ivar,[coder decodeObjectForKey:proName]);
            }
        }
        free(attrs);
    }
    free(pros);
    return [self init];
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
    //獲取全部的屬性
    unsigned int count = 0;
    objc_property_t *pros = class_copyPropertyList([self class], &count);
    //遍歷屬性
    for (int i = 0; i < count; i++) {
        objc_property_t pro = pros[i];
        unsigned int c = 0;
        //獲取實例變量的名稱
        NSString *proName = [NSString stringWithUTF8String:property_getName(pro)];
        //經過當前的屬性 獲取該屬性的特徵
        objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c);
        //遍歷特徵 可以獲得其類型以及數值等內容
        for (int j = 0; j < c; j++) {
            objc_property_attribute_t attr = attrs[j];
            if (strcmp(attr.name, "V") == 0) {//若是是特徵的名稱
                //獲取當前類對應特徵名稱的實例變量
                Ivar ivar = class_getInstanceVariable(self.class, attr.value);
                //獲得該實例變量的數值
                id object = object_getIvar(self, ivar);
                NSLog(@"%@",object);
                //歸檔
                [aCoder encodeObject:object forKey:proName];
            }
            
        }
        free(attrs);
    }
    free(pros);
}

@end


-------------繼承的方式以下-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//
//  ZJAutoCoding.h
//
//  Created by Jason_Msbaby on 15/10/13.
//  Copyright © 2015年 張傑. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 自動歸檔序列化
 須要繼承該類
 
 - returns:
 */
@interface ZJAutoCoding : NSObject <NSCoding>

/**
 *  全自動動態加載屬性 實現反歸檔
 *
 *  @param coder
 *
 *  @return
 */
- (instancetype)initWithCoder:(NSCoder *)coder;
/**
 *  全自動動態加載屬性 實現歸檔
 *
 *  @param aCoder
 */
-(void)encodeWithCoder:(NSCoder *)aCoder;
@end





//
//  ZJAutoCoding.m
//  UI高級2
//
//  Created by Jason_Msbaby on 15/10/13.
//  Copyright © 2015年 張傑. All rights reserved.
//

#import "ZJAutoCoding.h"
#import <objc/message.h>
#import <objc/runtime.h>

@implementation ZJAutoCoding


- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        //獲取全部屬性
        unsigned int count = 0;
        objc_property_t *pros = class_copyPropertyList(self.class, &count);
        //遍歷屬性
        for (int i = 0; i < count; i++) {
            objc_property_t pro = pros[i];
            //當前屬性對應的名
            NSString *proName = [NSString stringWithUTF8String:property_getName(pro)];
            unsigned int c = 0;
            //獲取全部特徵
            objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c);
            //遍歷全部特徵
            for (int j = 0; j < c; j++ ) {
                objc_property_attribute_t attr = attrs[j];
                //這裏的V指的是知道屬性對應的成員變量的名稱 例如name屬性  在這裏的特徵值則爲 V:_name 咱們須要的是_name
                if (strcmp(attr.name, "V") == 0) {
                    //而後咱們須要獲取實例進行賦值操做
                    Ivar ivar = class_getInstanceVariable(self.class, attr.value);
                    object_setIvar(self, ivar,[coder decodeObjectForKey:proName]);
                }
            }
            free(attrs);
        }
        free(pros);
        
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
    //獲取全部的屬性
    unsigned int count = 0;
    objc_property_t *pros = class_copyPropertyList([self class], &count);
    //遍歷屬性
    for (int i = 0; i < count; i++) {
        objc_property_t pro = pros[i];
        unsigned int c = 0;
        //獲取實例變量的名稱
        NSString *proName = [NSString stringWithUTF8String:property_getName(pro)];
        //經過當前的屬性 獲取該屬性的特徵
        objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c);
        //遍歷特徵 可以獲得其類型以及數值等內容
        for (int j = 0; j < c; j++) {
            objc_property_attribute_t attr = attrs[j];
            if (strcmp(attr.name, "V") == 0) {//若是是特徵的名稱
                //獲取當前類對應特徵名稱的實例變量
                Ivar ivar = class_getInstanceVariable(self.class, attr.value);
                //獲得該實例變量的數值
                id object = object_getIvar(self, ivar);
                NSLog(@"%@",object);
                //歸檔
                [aCoder encodeObject:object forKey:proName];
            }
            
        }
        free(attrs);
    }
    free(pros);
}

@end
相關文章
相關標籤/搜索