面试题答案
一键面试实现原理
在Objective-C中,当向一个对象发送它无法识别的消息时,会进入动态方法解析阶段。resolveInstanceMethod
方法是这个阶段的一部分。
- 调用时机:运行时系统首先会在类的方法列表中查找是否有与消息对应的方法实现。如果找不到,就会调用类的
+ (BOOL)resolveInstanceMethod:(SEL)sel
类方法。这个方法提供了一个机会,让开发者在运行时动态地为类添加方法实现。 - 动态添加方法:在
resolveInstanceMethod
方法中,可以使用class_addMethod
函数动态地向类中添加方法实现。如果成功添加了方法,就返回YES
,这样运行时系统会重新发送该消息,对象就能响应;如果返回NO
,运行时系统会进入备用接收者阶段。
常见应用场景
消息转发优化:在一些情况下,类中可能有很多相似功能的方法,但不想在编译时就定义所有方法。例如,有一个日志记录类,希望可以根据不同的日志级别动态生成日志记录方法,如logDebug:
,logInfo:
,logError:
等。
示例代码如下:
#import <Foundation/Foundation.h>
@interface Logger : NSObject
@end
@implementation Logger
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSString *selString = NSStringFromSelector(sel);
if ([selString hasPrefix:@"log"]) {
class_addMethod(self, sel, (IMP)logFunction, "v@:@");
return YES;
}
return [super resolveInstanceMethod:sel];
}
void logFunction(id self, SEL _cmd, NSString *message) {
NSLog(@"%@", message);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Logger *logger = [[Logger alloc] init];
[logger performSelector:NSSelectorFromString(@"logDebug:") withObject:@"This is a debug log"];
}
return 0;
}
在上述代码中,Logger
类在运行时根据接收到的消息动态添加日志记录方法,避免了在编译时定义大量相似方法,提高了代码的灵活性。