美文网首页
同一个类的多Category中通过runtime Method

同一个类的多Category中通过runtime Method

作者: Cwwng | 来源:发表于2020-10-28 11:09 被阅读0次

    1、Person一个分类Method swizzling方法。

    Person类中实例方法 eatAction。
    Person+First分类方法在+load方法Method swizzling 方法firstEatAction。
    结论:交换IMP后,调用firstEatAction,再调用eatAction。

    #import "Person.h"
    
    @implementation Person
    
    - (void)eatAction {
        
        NSLog(@"Person eat");
    }
    @end
    
    #import "Person+First.h"
    #import <objc/runtime.h>
    
    @implementation Person (First)
    
    + (void)load {
        
        Method superMethod = class_getInstanceMethod(self, @selector(eatAction));
        Method categoryMethod = class_getInstanceMethod(self, @selector(firstEatAction));
        
        method_exchangeImplementations(superMethod, categoryMethod);
    }
    
    - (void)firstEatAction {
        
        NSLog(@"Person First Eat");
        [self firstEatAction];
    }
    @end
    
    2020-10-28 10:30:42.476728+0800 Test[79946:3618138] Person First Eat
    2020-10-28 10:30:42.476922+0800 Test[79946:3618138] Person eat
    

    2、Person的两个分类,Method swizzling同一个方法firstEatAction。

    Person类中实例方法 eatAction。
    Person+First分类方法在+load方法Method swizzling 方法firstEatAction。
    Person+Second分类方法在+load方法Method swizzling 方法firstEatAction。
    结论:两个Category中,若swizzling自定义方法名相同,则自定义的方法不会调用。因为两次交换IMP正好不变。

    #import "Person+Second.h"
    #import <objc/runtime.h>
    
    @implementation Person (Second)
    
    + (void)load {
        
        Method superMethod = class_getInstanceMethod(self, @selector(eatAction));
        Method categoryMethod = class_getInstanceMethod(self, @selector(firstEatAction));
        
        method_exchangeImplementations(superMethod, categoryMethod);
    }
    
    - (void)firstEatAction {
        
        NSLog(@"Person Second Eat");
        [self firstEatAction];
    }
    
    @end
    
    2020-10-28 10:41:43.364859+0800 Test[80037:3628168] Person eat
    

    3、Person的两个分类,Method swizzling不同方法。

    Person类中实例方法 eatAction。
    Person+First分类方法在+load方法Method swizzling 方法firstEatAction。
    Person+Second分类方法在+load方法Method swizzling 方法secondEatAction。
    结论:两个Category中,如swizzling自定义方法名不同,则自定义的方法都会被调用,调用顺序Compile Sources中在后边的先调用。
    例如:[person run] [person2 run2] [person1 run1] Compile Sources中先person1。
    根据Compile Sources顺序,person2的category中 +load方法先调用后,person -> run2 -> run。
    person1的category中 +load方法调用后,person –> run1 -> run2 -> run。

    #import "Person+Second.h"
    #import <objc/runtime.h>
    
    @implementation Person (Second)
    
    + (void)load {
        
        Method superMethod = class_getInstanceMethod(self, @selector(eatAction));
        Method categoryMethod = class_getInstanceMethod(self, @selector(secondEatAction));
        
        method_exchangeImplementations(superMethod, categoryMethod);
    }
    
    - (void)secondEatAction {
        
        NSLog(@"Person Second Eat");
        [self secondEatAction];
    }
    
    @end
    
    2020-10-28 10:55:15.284390+0800 Test[80133:3638581] Person First Eat
    2020-10-28 10:55:15.285932+0800 Test[80133:3638581] Person Second Eat
    2020-10-28 10:55:15.286310+0800 Test[80133:3638581] Person eat
    
    截屏2020-10-28 上午10.54.59.png

    相关文章

      网友评论

          本文标题:同一个类的多Category中通过runtime Method

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