美文网首页
runtime与model

runtime与model

作者: 那个人一定不是我 | 来源:发表于2017-09-20 16:41 被阅读0次

    使用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

          本文链接:https://www.haomeiwen.com/subject/diuosxtx.html