美文网首页
MY_Runtime机制

MY_Runtime机制

作者: _Weak | 来源:发表于2016-11-02 16:34 被阅读17次

    Runtime: 运行时机制

    OC语言就是运行时机制, 在编译时不检测调用那个方法, 在运行时进行调用方法

    ( 一 ) Runtime之消息发送机制
    底层都是实现了[p performSelector:@selector(eat)];

    Person * p = [[Person alloc]init];
    [p performSelector:@selector(eat)];
    
    1. 第一步 导入头文件
    #import <objc/message.h>
    
    1. 第二步 使用objc_msgSend消息机制
      Target - BulidSetting - 搜索msg - 设置为NO
    /*** 使用消息机制 ***/
        objc_msgSend(p, @selector(eat));
        objc_msgSend(p, @selector(run:),10);
    
    1. 运行时调用类方法
    /*** 调用类方法 ***/
        Class personClass = [Person class];
        [[Person class] performSelector:@selector(eat)];
        [personClass performSelector:@selector(eat)];
        objc_msgSend(personClass, @selector(eat));
    

    ( 二 ) Runtime之交换方法

    1. 第一步 导入头文件
    #import <objc/message.h>
    
    1. 实现交换方法
    /*** 交换方法机制 ***/
        method_exchangeImplementations(<#Method m1#>, <#Method m2#>)
    
    1. 获取类方法和对象方法
    //1. 获取对象方法
        class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)
        //2. 获取类方法
        class_getClassMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>)
    
    1. 实现交换方法
    Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
        Method MY_imageNamedMethod =  class_getClassMethod([UIImage class], @selector(MY_imageNamed:));
        //实现交换方法
        method_exchangeImplementations(imageNamedMethod, MY_imageNamedMethod);
    

    五 Runtime之动态添加方法

    1. 动态加载方法
    //1. 动态加载类方法
    +(BOOL)resolveClassMethod:(SEL)sel
    //2. 动态加载对象方法
    +(BOOL)resolveInstanceMethod:(SEL)sel
    
    //1. 动态加载无参方法
        [p performSelector:@selector(eat)];
        //2. 动态加载有参方法
        [p performSelector:@selector(eat:) withObject:@123];
    
    1. 动态加载对象方法
      VC中动态调用没有定义的eat方法
    Person * p = [[Person alloc]init];
    [p performSelector:@selector(eat)];
    

    Person.m中实现动态加载

    #import "Person.h"
    #import <objc/message.h>
    
    @implementation Person
    
    ////1. 动态加载类方法
    //+(BOOL)resolveClassMethod:(SEL)sel
    ////2. 动态加载对象方法
    //+(BOOL)resolveInstanceMethod:(SEL)sel
    
    #pragma mark - BOOL)resolveInstanceMethod:(SEL)sel
    //1. 动态添加方法, 首先要实现这个resolveInstanceMethod方法
    //2. resolveInstanceMethod调用: 当一个方法没有实现, 又被调用了, 就会调用reolve
    //3. resolveInstanceMethod作用: 就知道了哪些方法没有被调用, 从而动态添加该方法
    //4. sel: 被调用了 但没有被实现的方法
    +(BOOL)resolveInstanceMethod:(SEL)sel{
        if (sel == @selector(eat)) {
            NSLog(@"%@",NSStringFromSelector(@selector(eat)));
            //动态添加eat方法
            /*** 
             __unsafe_unretained Class cls:   给哪个类添加方法
             SEL name                     :   添加方法的名字编号
             IMP imp                      :   方法实现, 函数入口(C), 函数名, (IMP)强转
             const char *types            :   方法类型: [void: v , id: @ , sel: : ]
             ***/
            class_addMethod(self, sel, (IMP)eatAction, "v@:");
            //处理完
            return YES;
        }
        return YES;
    }
    //定义C语言函数方法
    //隐式参数: 没有返回值, 参数(id SEL)
    //void(id, SEL)
    void eatAction(id self, SEL _cmd){
        NSLog(@"调用eat%@ %@",self, NSStringFromSelector(_cmd));
    }
    

    相关文章

      网友评论

          本文标题:MY_Runtime机制

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