面试题答案
一键面试动态方法解析阶段具体流程
- 对象接收到无法识别的消息:当一个对象收到它无法以常规方式(即类的方法列表中不存在该方法)响应的消息时,消息转发机制启动,首先进入动态方法解析阶段。
- 类方法的动态解析:运行时系统会首先调用类的
+ (BOOL)resolveClassMethod:(SEL)sel
方法。如果这个类方法实现了,并且返回YES
,那么开发者就可以在这个方法中动态添加类方法的实现。例如,可以使用class_addMethod
函数向类中添加类方法的实现。 - 实例方法的动态解析:如果
+ (BOOL)resolveClassMethod:(SEL)sel
没有处理这个消息或者返回NO
,运行时系统接着会调用+ (BOOL)resolveInstanceMethod:(SEL)sel
方法。如果此方法实现了并且返回YES
,开发者可以在该方法中动态添加实例方法的实现,同样可以使用class_addMethod
函数。
动态方法解析阶段的作用
- 提供灵活性:允许开发者在运行时动态地为类添加方法,而不需要在编译时就确定所有的方法。这对于一些需要在特定场景下才动态生成方法的情况非常有用,比如在某些框架中,根据配置文件动态添加特定的处理方法。
- 错误处理的柔性:避免因为未识别的消息直接导致程序崩溃,而是提供了一种机会让程序在运行时动态修复这种情况,增强了程序的健壮性。
开发者介入并处理未识别消息的方式
- 实现
+ (BOOL)resolveClassMethod:(SEL)sel
方法:开发者在这个方法中判断传入的SEL
(方法选择器),如果是需要处理的未识别类方法消息,就使用class_addMethod
动态添加类方法的实现。例如:
+ (BOOL)resolveClassMethod:(SEL)sel {
if (sel == @selector(someClassMethod)) {
class_addMethod(self, sel, (IMP)someClassMethodImplementation, "v@:");
return YES;
}
return NO;
}
这里someClassMethodImplementation
是开发者定义的具体实现函数。
2. 实现+ (BOOL)resolveInstanceMethod:(SEL)sel
方法:类似于类方法的处理,如果是未识别的实例方法消息,在这个方法中通过class_addMethod
添加实例方法实现。例如:
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(someInstanceMethod)) {
class_addMethod(self, sel, (IMP)someInstanceMethodImplementation, "v@:");
return YES;
}
return NO;
}
这里someInstanceMethodImplementation
是实例方法的具体实现函数。通过这种方式,开发者可以在动态方法解析阶段对未识别的消息进行合理处理。