通过类名调用被分类覆盖的原方法
通过类名调用被分类覆盖的原方法
在分类中重写方法后,会将原方法进行覆盖。若想继续执行原方法则可通过方法列表和方法指针找到原方法
- (void)viewDidLoad {
[super viewDidLoad];
Class currentClass = [TestClass class];
TestClass *my = [[TestClass alloc] init];
[my printName];
if (currentClass) {
unsigned int methodCount;
Method *methodList = class_copyMethodList(currentClass, &methodCount);
IMP lastImp = NULL;
SEL lastSel = NULL;
for (NSInteger i = 0; i < methodCount; i++) {
Method method = methodList[i];
NSString *methodName = [NSString stringWithCString:sel_getName(method_getName(method))
encoding:NSUTF8StringEncoding];
if ([@"printName" isEqualToString:methodName]) {
lastImp = method_getImplementation(method);
lastSel = method_getName(method);
// 按照方法列表遍历(分类的方法在原方法的前面),如果第一次拿到的printName就break出去,则获取的是分类的方法。如果继续遍历,则拿到的最后一个就是类本身的原方法。
// break;
} //lastSel 是原方法的编码
}
typedef void (*fn)(id,SEL);
if (lastImp != NULL) {
fn f = (fn)lastImp;
f(my, lastSel); // 执行方法
}
free(methodList);
}
}
TestClass.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TestClass : NSObject
- (void)printName;
@end
NS_ASSUME_NONNULL_END
TestClass.m
#import "TestClass.h"
@implementation TestClass
- (void)printName{
NSLog(@"printName%s==TestClass",__func__);
}
@end
TestClass+addNewMethod.h
#import "TestClass.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestClass (addNewMethod)
- (void)printName;
@end
NS_ASSUME_NONNULL_END
TestClass+addNewMethod.m
#import "TestClass+addNewMethod.h"
@implementation TestClass (addNewMethod)
- (void)printName{
NSLog(@"printName%s==addNewMethod",__func__);
}
@end
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!