OC 调用方法崩溃前做了哪些事情

2024-11-07  本文已影响0人  liang1030

在OC(Objective-C)中,当调用方法导致崩溃前,runtime系统执行了一系列步骤来尝试解析和转发消息。以下是这些步骤的详细解释:

一、方法查找与缓存

Cache查找:首先,runtime系统会在方法缓存(cache_t)中查找目标方法。如果找到了,就直接调用该方法,这是最高效的方式。

类方法列表查找:如果Cache中未找到目标方法,runtime系统会进入类对象的方法列表中查找。这个列表包括了类本身定义的方法和分类(Category)中添加的方法。

父类查找:如果类方法列表中也没有找到,runtime系统会继续向上查找父类,重复上述步骤,直到找到方法或者到达根类(如NSObject)为止。

二、动态解析

resolveInstanceMethod/resolveClassMethod:如果runtime系统在Cache和类的方法列表(包括父类)中都找不到要执行的方法,会调用resolveInstanceMethod:(针对对象方法)或resolveClassMethod:(针对类方法)来给我们一次动态添加方法实现的机会。这些方法可以在运行时动态地向类添加方法,并返回YES表示成功添加,或者返回NO表示未添加。

• 如果在这些方法中动态添加了方法,并且返回了YES,那么runtime系统会再次尝试查找并调用该方法。
• 如果未添加方法但返回了YES(这通常是不推荐的),那么会进入消息转发流程。
• 如果返回了NO,则不会进入消息转发流程,而是直接抛出异常。

三、消息转发

1. forwardingTargetForSelector:如果动态解析阶段未处理该方法调用,runtime系统会调用forwardingTargetForSelector:来允许我们指定另一个对象来处理该消息。这个方法可以返回一个不同的对象,该对象将接收原始选择器并尝试执行它。

2. methodSignatureForSelector:如果forwardingTargetForSelector:未返回有效的目标对象,那么会调用methodSignatureForSelector:来允许我们返回一个方法签名(NSMethodSignature),该方法签名描述了可以接收该选择器的对象的方法参数和返回类型。这是为了准备进入forwardInvocation:阶段。

3. forwardInvocation:最后,如果上述步骤都未成功处理该方法调用,runtime系统会调用forwardInvocation:方法。这个方法接收一个NSInvocation对象,该对象封装了原始的消息和参数。我们可以在这个方法中自定义如何处理该消息,例如将消息转发给另一个对象或执行其他逻辑。

四、崩溃

如果经过上述所有步骤后仍未找到可执行的方法,那么runtime系统会抛出“unrecognized selector sent to instance”异常,导致程序崩溃。

综上所述,OC在调用方法崩溃前做了大量的工作来尝试解析和转发消息,包括方法查找与缓存、动态解析和消息转发等步骤。这些机制为开发者提供了在运行时动态处理未知方法调用的机会,从而增加了程序的灵活性和健壮性。

上一篇 下一篇

猜你喜欢

热点阅读