runtime与model

使用runtime进行model进行简单操作
Model 根类

/*Model 类*/
@interface GModel : NSObject

+ (instancetype) readPropertyFromDic:(NSDictionary*)dic;
- (NSDictionary*) dicAboutProperties;

@end
@implementation GModel


+ (instancetype) readPropertyFromDic:(NSDictionary*)infoDic{
    
    GModel* obj = [[self alloc] init];
    
    Class c = self.class;
    while (c && c != [GModel class]) {
        
        unsigned int outCount = 0;
        Ivar* ivars = class_copyIvarList(c, &outCount);
        /**class_copyPropertyList只获取“@property”声明的成员变量(获取的成员变量前面没有“_”),
         注意class_copyIvarList获取“{}”中的成员变量也不会主动加“_”**/
        
        for (int i = 0; i < outCount; i++) {
            Ivar ivar = ivars[i];
            NSString* key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            key = [key substringFromIndex:1];  // 去掉下划线_
            id value = infoDic[key];
            
            if(value == nil) continue;
            
            NSString* type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            NSRange range = [type rangeOfString:@"@"];
            if (range.location != NSNotFound) {
                type = [type substringWithRange:NSMakeRange(2, type.length - 3)];
                Class typeClass = NSClassFromString(type);
                if ([typeClass isSubclassOfClass:[GModel class]]) {
                    
                    value = [typeClass readPropertyFromDic:value];
                }
            }
            
            [obj setValue:value forKeyPath:key];
        }
        
        free(ivars);
        c = [c superclass];
    }
    
    return obj;
}

- (NSDictionary*) dicAboutProperties{
    
    NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
    
    Class c = self.class;
    while (c && c != [GModel class]) {
        
        unsigned int outCount = 0;
        Ivar* ivars = class_copyIvarList(c, &outCount);

        for (int i = 0; i < outCount; i++) {
            Ivar ivar = ivars[i];
            NSString* key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            id value = [self valueForKeyPath:key];
            
            NSString* type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            NSRange range = [type rangeOfString:@"@"];
            if (range.location != NSNotFound) {
                type = [type substringWithRange:NSMakeRange(2, type.length - 3)];
                Class typeClass = NSClassFromString(type);
                if ([typeClass isSubclassOfClass:[GModel class]]) {
                    value = [value dicAboutProperties];
                }else if(![type hasPrefix:@"NS"]){
                    value = nil; //其他类型不处理
                }
            }
            
            key = [key substringFromIndex:1];  // 去掉下划线_
            [dic setValue:value forKey:key];
        }
        
        free(ivars);
        c = [c superclass];
    }

    return dic;
}

@end

测试对象Person Man Society

@interface Person : GModel

@property (nonatomic, strong) NSString* name;
@property (nonatomic, assign) NSUInteger age;

@end


@interface Man : Person

@property (nonatomic, strong) NSString* other;

@end


@interface Society : GModel

@property (nonatomic, strong) Man* aMan;
@property (nonatomic, strong) Person* aPerson;
@property (nonatomic, strong) NSNumber* count;

@end

进行字典数据与model的互转

    NSDictionary* personData  = @{@"name" : @"Mrs",
                                  @"age"  : @29};
    
    NSMutableDictionary* manData = [NSMutableDictionary dictionaryWithDictionary:personData];
    manData[@"other"] = @"I'm a man";
    
    NSDictionary* societyData = @{@"aMan"    : manData,
                                  @"aPerson" : personData,
                                  @"count"   : @"2"
                                  };
    
    ///通过数据创建model对象
    Person*   aPerson  = [Person readPropertyFromDic:personData];
    Man*      aMan     = [Man readPropertyFromDic:manData];
    Society*  aSociety = [Society readPropertyFromDic:societyData];
    
    ///通过model对象获取属性值字典
    NSDictionary* outPerson  = [aPerson  dicAboutProperties];
    NSDictionary* outMan     = [aMan     dicAboutProperties];
    NSDictionary* outSociety = [aSociety dicAboutProperties];

参考:
OC最实用的runtime总结
Ivar 详解

你可能感兴趣的:(runtime与model)