Model--runtime

  • 运用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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,753评论 7 64
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,856评论 0 9
  • 1.基本就是 MJ 字典转model 的实现 原理 (当然内部有很多的细节,比方说 数组 ,model 里面套mo...
    fangtang0101阅读 206评论 0 0
  • 这几天很忙,在北京参加培训的同时,还见各路朋友。还在规划着写书的事情。 规划这个事情,看似简单,写成文字记录或者画...
    千云变阅读 126评论 0 0
  • 回顾自己走过的乌漆嘛嘿的路,总有人为我点灯照我前行,虽然还是在摸黑前行,但至少有那么些瞬间让我感动不已,为我点灯的...
    云中君style阅读 794评论 0 1