美文网首页
Runtime&KVC知识回顾

Runtime&KVC知识回顾

作者: 遮住眼睛的草纸 | 来源:发表于2018-05-29 20:18 被阅读0次

    KVC底层原理

    遍历字典,一一赋值

    -(instancetype)initWithDict:(NSDictionary * )dict{
        MyModel *item = [[MyModel alloc]init];
            
        [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull value, BOOL *
               [item setValue:value forKey:key];
        }];
        return item;
       }
    

    例如:name

    • 1.先找setName方法
    • 2.找不到setName方法就找name属性
    • 3.找不到name属性就找_name属性
    • 4.如果都找不到,就报错

    Runtime

    方法使用场景和注意要点

    • 交换方法

    +(void)load{
        Method imageNameMethod = class_getClassMethod(self, @selector(imageNamed:));
        Method my_imageNameMethod = class_getClassMethod(self, @selector(my_ImageNamed:));
        method_exchangeImplementations(imageNameMethod, my_imageNameMethod);
    }
    
    +(UIImage *)my_ImageNamed:(NSString *)Name{
        UIImage * image = [UIImage my_ImageNamed:Name];
        if (image) {
            NSLog(@"加载成功");
        }else{
            NSLog(@"加载失败");
        }
        return image;
    }
    

    应用场景:希望扩充系统分类方法的时候。不改变原有系统方法的同时,实现自定义扩展方法。

    要点:将交换实现写在 load 方法中,在加载程序的时候就会调用

    • 动态添加属性

    .h文件
    @property NSString * name;//只是申明set,和get方法,并不实现
    
    .m文件
    
    -(void)setName:(NSString *)name{
        /*
        *objc_setAssociatedObject(id  _Nonnull object, const void * _Nonnull key, id  _Nullable value, objc_AssociationPolicy policy)
        *object:哪个类
        *key:属性名
        *name:参数
        *policy:策略
        */
        objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    -(NSString *)name{
        return objc_getAssociatedObject(self, "name");
    }
    
    
    

    应用场景:分类添加属性

    • 动态添加方法(消息转发)

    void doit(id self,SEL _cmd){//self和_cmd隐式参数,必须要
        NSLog(@"进来了");
    }
    
    +(BOOL)resolveInstanceMethod:(SEL)sel{
        if (sel == NSSelectorFromString(@"eat")) {
            class_addMethod(self, sel, (IMP)doit, "v@:");
            
            return YES;
        }
        return [super resolveInstanceMethod:sel];
    }
    

    应用场景:没必要一次性实现,付费用户功能等

    要点:调用一个不存在的方法,如果找不到,会转发消息到resolveInstanceMethod方法,在resolveInstanceMethod中处理。

    (持续编辑中)

    相关文章

      网友评论

          本文标题:Runtime&KVC知识回顾

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