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