美文网首页
Model--runtime

Model--runtime

作者: wpf_register | 来源:发表于2016-07-28 13:59 被阅读17次
    • 运用runtime创建基类,也可以快速方便的实现model 与字典的相互转化
    • 下面的方法只是实现简单的字典转model,要实现复合model及包含数组的模型转换还需要做一其它处理。
    • 各种json 转 model大都都使用运行时动态获取属性名的方法,来过行字典转模型,但都使用了KVC :setValue:forKey,只是多了一些判空和嵌套的逻辑处理。
    #import "NSObject+JsonExtension.h"  //对基类添加扩展
    #import <objc/runtime.h>  //一定要导入runtime头文件
    
    @implementation NSObject (JsonExtension)
    
    + (instancetype)objectWithDic:(NSDictionary*)dic{
        
        NSObject *obj = [[self alloc]init];
        [obj setDic:dic];
        return obj;
    }
    
    - (void)setDic:(NSDictionary*)dic{
        
        Class c = [self class];
         while (c && c != [NSObject class]) {
    
            unsigned int count = 0;
            
         // Method *methodList = class_copyMethodList(c, &count);
         //列举属性及实例变量
         //Ivar *ivars = class_copyIvarList(c, &count);
         //只列举用@property修饰的属性
        objc_property_t *propertyList = class_copyPropertyList(c, &count);
    
            for (int i = 0; i< count; i++) {
               
                objc_property_t property = propertyList[i];
                NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
                id value = dic[propertyName];
                //值nil,说明字典的key没有相应model属性
                if (value == nil;  continue;
                [self setValue:value forKeyPath:propertyName];
            }
            //释放数组
            free(propertyList);
            //从本类到父类
            c = [c superclass];    
        }
    }
    @end
    

    PS: 关于runtime,除了字典转model外,常用的就是方法交换

    一般不建议在分类中重写当前类的方法,因为多个类目都重写一个方法后,系统无法确定重写后的方法优先级,同时重写也覆盖系统方法,且在类目中无法使用super.

    #import <objc/runtime.h>
    #import "UIImage+Extentsion.h"
    @implementation UIImage (Extentsion)
    + (instancetype)imageWithName:(NSString*)name{
        //方法已经交换,所以这边实际上调用的是系统方法
        //即imageNamed:调用的是新的方法,而imageWithName:则是调用系统方法,而不是自身。
        UIImage *image = [self imageWithName:name];
        if (image == nil) {
            NSLog(@"加载出错");
        }
        NSLog(@"这是替换后的方法");
        return image;
    }
    
    //分类加载到内存时调用,且只调用一次
    + (void)load{
        //class_getInstanceMethod(self, @selector(...));    //获取实例方法
        Method method1 = class_getClassMethod(self, @selector(imageWithName:));
        Method method2 = class_getClassMethod(self, @selector(imageNamed:));
    
        method_exchangeImplementations(method1, method2);
        
    }
    @end
    
    

    相关文章

      网友评论

          本文标题:Model--runtime

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