OC实现分类中调用原类的同名方法

    在使用分类(category)对现有类进行功能扩展时,分类中增加的方法会被优先执行,也就是说分类中实现了与原类中某个同名的方法时,在调用的这个方法时调用的是分类中的实现,而不会调用原类中的实现。

    分类中的方法会被优先调用是因为在runtime注册类时,会将分类的方法列表插入到类对象方法列表中的前面位置。在调用方法时,会从类对象中的方法缓存列表和方法列表中顺序查找,找到之后就去调用对应的方法实现。所以在查找时会优先查找到分类的方法。

    如果希望在调用分类方法时也能调用到原类中对应的同名方法,那么需要通过runtime来读取类对象中的方法列表,然后倒序查询方法并调用。

示例代码如下:

// 原类

@implementation ViewController

- (void)testMethod {

    NSLog(@"%@  %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));

}

@end

// Category中的实现

#import "ViewController+test.h"

#import

@implementation ViewController (test)

- (void)testMethod {

    NSLog(@"ViewController+test  %@", NSStringFromSelector(_cmd));

    unsigned int methodCount;

    // 获取类的方法列表

    Method *methodList = class_copyMethodList([self class], &methodCount);

    for (int i = methodCount - 1; i > 0; i--) {

        Method method = methodList[i];

        SEL sel = method_getName(method);                        // 方法名称

        IMP imp = method_getImplementation(method);      // 指向方法执行地址的指针

        NSLog(@"方法名称: %@", [NSString stringWithUTF8String:sel_getName(sel)]);

        if (sel == _cmd) {

            void (*fundtion)(id, SEL) = (void *)imp;

            fundtion(self, sel);

            break;

        }

    }

    free(methodList); // 在C语言中但凡用到了 new/creat/copy 这类函数,就要手动释放指针

    // 执行任务 (原类中先执行, 如果希望分类的任务先执行,那么这里的任务代码放在testMethod代码块内的前面)

}

你可能感兴趣的:(OC实现分类中调用原类的同名方法)