美文网首页
Runtime方法交换-2021-02-24-周三

Runtime方法交换-2021-02-24-周三

作者: 勇往直前888 | 来源:发表于2021-02-25 11:05 被阅读0次

    runtime中类似@selector(coding)这样的是函数名;类似(IMP)coding才是函数执行体的入口指针。
    将函数分为函数名和函数执行体两部分,就带来了很大的灵活性;

    class_getInstanceMethod这个函数可以通过函数名得到对应的函数执行体;

    method_exchangeImplementations这个函数可以交换两个函数的执行体;

    • 本来函数名和函数执行体是一一对应的,很好理解;

    • 如果执行一次method_exchangeImplementations,交换了两个函数的执行体,那么函数名和函数执行体就错位了;会显得很奇怪;

    • 如果再执行一次method_exchangeImplementations,把交换过的执行体再交换一次,那么就被换回来了。这样经过两次交换之后,相当于没交换,函数名和函数执行体就又对应起来了;一切又恢复正常了。

    给Person添加两个方法

    // 写代码
    - (void)coding {
        NSLog(@"小明在写代码");
    }
    
    // 吃饭
    - (void)eating {
        NSLog(@"小明在吃饭");
    }
    

    做个测试界面

    image.png

    方法交换

    // 执行交换
    - (void)change {
        Method codingMethod = class_getInstanceMethod(self.person.class, @selector(coding));
        Method eatingMethod = class_getInstanceMethod(self.person.class, @selector(eating));
        method_exchangeImplementations(codingMethod, eatingMethod);
    }
    

    这里不管函数名和函数执行体是否对应,反正就交换一次

    状态记忆

    @interface ExchangeViewController ()
    
    // 交换按钮,记忆按钮的状态
    @property (weak, nonatomic) IBOutlet UISwitch *exchangeSwitch;
    
    @property (strong, nonatomic) Person *person;
    
    // 记忆是否交换过
    @property (assign, nonatomic) BOOL isChanged;
    
    @end
    

    交换按钮的状态;是否交换过,这两个状态是需要记忆的

    按钮响应

    #pragma mark - action
    // 根据记忆状态,交换函数执行体
    - (IBAction)exchangeSwitchChanged:(id)sender {
        // 还没有交换过,并且要求交换;那么交换一次
        if ((self.exchangeSwitch.isOn) && !self.isChanged) {
            [self change];
            self.isChanged = YES;
        }
        
        // 已经交换过,并且要求没交换前的原始函数;那么交换一次,交换回来
        if ((!self.exchangeSwitch.isOn) && self.isChanged) {
            [self change];
            self.isChanged = NO;
        }
    }
    
    // 写代码
    - (IBAction)writeButtonTouched:(id)sender {
        [self.person coding];
    }
    
    // 吃饭
    - (IBAction)eatButtonTouched:(id)sender {
        [self.person eating];
    }
    

    测试一下

    • 正常状态
    image.png image.png
    • 交换状态
    image.png image.png

    Demo地址

    RuntimeDemo

    相关文章

      网友评论

          本文标题:Runtime方法交换-2021-02-24-周三

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