MST
星途 面试题库

面试题:Objective-C中Runtime如何动态添加方法

请简述在Objective-C中,利用Runtime动态添加方法的基本步骤,并给出一个简单的代码示例,比如为某个类在运行时添加一个新的实例方法。
28.1万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 基本步骤

    • 动态方法解析:在类的+ (BOOL)resolveInstanceMethod:(SEL)sel方法中,使用class_addMethod函数动态添加方法实现。当向对象发送一个它当前没有实现的方法时,会调用这个类方法,给我们一个动态添加方法的机会。
    • 备用接收者:如果动态方法解析没有处理该方法,runtime会调用- (id)forwardingTargetForSelector:(SEL)aSelector方法,尝试寻找其他对象来处理这个消息。
    • 完整的消息转发:如果备用接收者也没有处理该消息,runtime会进入完整的消息转发流程,包括- (void)forwardInvocation:(NSInvocation *)anInvocation- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector方法。
  2. 代码示例

#import <objc/runtime.h>
#import <Foundation/Foundation.h>

@interface Person : NSObject
@end

// 实现动态添加的方法
void runMethod(id self, SEL _cmd) {
    NSLog(@"I'm running!");
}

@implementation Person

// 动态方法解析
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(run)) {
        class_addMethod(self, sel, (IMP)runMethod, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        [person performSelector:@selector(run)];
    }
    return 0;
}

在上述代码中:

  • 首先定义了Person类,它没有run方法。
  • 然后定义了runMethod函数,这将是动态添加的run方法的实现。
  • Person类的+ (BOOL)resolveInstanceMethod:(SEL)sel方法中,当检测到要处理的SEL@selector(run)时,使用class_addMethod动态添加run方法的实现。
  • main函数中,创建Person对象并通过performSelector:调用run方法,由于动态添加方法的机制,这个调用能够成功执行并打印出I'm running!