美文网首页
runtime相关

runtime相关

作者: Vijay_ | 来源:发表于2017-12-05 03:33 被阅读8次

    修改系统方法

    //先要导入message类
    #import <objc/message.h>
    @implementation UIImage (Image)
    +(void)load{
        //class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>) 这个是获取对象方法 -
        //获取imageNamed 类方法 +
        //获取vjimageNamed 类方法 +
        Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
        Method vjimageNamedMethod = class_getClassMethod([UIImage class], @selector(vj_imageNamed:));
        //交换两个方法(当调用imageNamed时是调用的vj_imageNamed 反之亦然  注意死循环)
        method_exchangeImplementations(imageNamedMethod, vjimageNamedMethod);
    }
    
    +(__kindof UIImage*)vj_imageNamed:(NSString*)name{
        UIImage *image = [self vj_imageNamed:name];
        if (!image) {
            NSLog(@"加载为空");
        }
        return  image;
    
    }
    @end
    
    

    动态添加方法

    Son *s =  [[Son alloc] init];
    //发送对象方法消息时会调用类的resolveInstanceMethod
    //发送类方法消息时会调用类的resolveClassMethod
        [s performSelector:@selector(haha:) withObject:@"hello"];
        void hahaIMP(id self,SEL _cmd , id num){
        NSLog(@"%@",num);
    }
    
    + (BOOL)resolveInstanceMethod:(SEL)sel{
        //判断方法编号
        if (sel == @selector(haha:)) {
    //添加方法,第三个参数是c语言的函数 需要先定义个函数
    //第四个参数是c语言函数的参数类型详情见帮助文档搜
    //"rumtime->Type Encodings"
            class_addMethod(self, sel, (IMP)hahaIMP, "v@:@");
            return YES;
        }
        return [super resolveClassMethod:sel];
    }
    

    动态给系统类添加属性(给分类添加属性)

    #import "NSObject+objName.h"
    #import <objc/message.h>
    @implementation NSObject (objName)
    //在分类的.h文件中 使用@proterpty只会生成属性的getset声明 不会去实现 也不会定义成员属性 因为分类定义不了属性
    //所以要重写getset方法  一个对象属性赋值其实就是 让一个对象里产生一个key关联另一个对象。
    
    - (NSString *)name{
        
        return objc_getAssociatedObject(self, "name");
    }
    
    - (void)setName:(NSString *)name{
        //第四个参数是关联策略就像定义属性时的(nonatomic,strong)
        objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end
    
    

    runtime+kvc 转换模型

    +(instancetype)createObjByDictionary:(NSDictionary*)dic{
        id obj = [[self alloc] init];
        
        //创建一个无符号整形变量 把地址值给下面方法 下面方法会对该变量进行处理赋值成员属性的个数
        unsigned int count = 0;
        //返回的是一个ivar数组  声明一个指针变量指向该数组
        Ivar *ivarList = class_copyIvarList(self, &count);
        
        for (int i = 0; i<count; i++) {
            //从数组中取出该Ivar指针类型的值
            //typedef struct objc_ivar *Ivar; Ivar是一个指针类型
            Ivar ivar = ivarList[i];
            //此处是获取到成员属性
            NSString *ivarName = [NSString stringWithUTF8String: ivar_getName(ivar)];
            NSString *ivarType = [NSString stringWithUTF8String: ivar_getTypeEncoding(ivar)];
            //KVC需要使用属性不是成员属性
            ivarName = [ivarName substringFromIndex:1];
            id value = dic[ivarName];
            //二级转换
            //值是字典 并且属性类型不是系统类(排除该属性声明是字典类型)
            if ([value isKindOfClass:[NSDictionary class]] && ![ivarType containsString:@"NS"]) {
                
                //把属性类型字符串中的转义符去掉
                NSRange range = [ivarType rangeOfString:@"\""];
                ivarType = [ivarType substringFromIndex:range.location+range.length];
                range = [ivarType rangeOfString:@"\""];
                ivarType = [ivarType substringToIndex:range.location];
                
                Class modelClass = NSClassFromString(ivarType);
                if (modelClass) {
                    //给value变量赋值该类型转换后的对象
                    value = [modelClass createObjByDictionary:value];
                }
            }
         
            [obj setValue:value forKey:ivarName];
        }
    
        
        return obj;
        
    }
    

    相关文章

      网友评论

          本文标题:runtime相关

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