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

2020-10-28  本文已影响0人  Cwwng

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
上一篇 下一篇

猜你喜欢

热点阅读