返回

iOS 底层探究:方法的慢速查找全解析

IOS

iOS 底层探究:方法的慢速查找

在上一篇文章中,我们介绍了方法的快速查找流程,即缓存查找。如果缓存中没有找到方法,系统就会进入到方法的慢速查找流程。

在慢速查找流程中,系统会通过消息转发机制和动态解析来定位并调用所需的方法。

消息转发机制

消息转发机制是 iOS 中的一种运行时机制,它允许对象在没有实现某个方法的情况下仍能收到并处理该方法的调用。

当一个对象收到一个它没有实现的方法调用时,系统会将这个调用转发给该对象的父类或其他对象。

消息转发机制的实现过程如下:

  1. 当一个对象收到一个它没有实现的方法调用时,系统会首先检查该对象是否实现了 forwardingTargetForSelector: 方法。
  2. 如果对象实现了 forwardingTargetForSelector: 方法,系统会调用该方法来询问对象是否希望将该方法调用转发给另一个对象。
  3. 如果对象返回了一个非空的对象,系统会将该方法调用转发给该对象。
  4. 如果对象返回了 nil,系统会检查该对象是否实现了 methodSignatureForSelector: 方法。
  5. 如果对象实现了 methodSignatureForSelector: 方法,系统会调用该方法来获取该方法的签名。
  6. 如果对象返回了一个非空的方法签名,系统会尝试动态解析该方法。
  7. 如果动态解析成功,系统会调用该方法。
  8. 如果动态解析失败,系统会向该对象发送一个 doesNotRecognizeSelector: 消息。

动态解析

动态解析是一种运行时机制,它允许系统在运行时查找并调用一个方法。

动态解析的过程如下:

  1. 系统会创建一个包含该方法选择器和方法签名的结构体。
  2. 系统会使用这个结构体来搜索该对象的类和父类,以查找该方法的实现。
  3. 如果系统找到了该方法的实现,系统会调用该方法。
  4. 如果系统没有找到该方法的实现,系统会向该对象发送一个 doesNotRecognizeSelector: 消息。

慢速查找流程

慢速查找流程的步骤如下:

  1. 系统会检查该对象是否实现了 forwardingTargetForSelector: 方法。
  2. 如果对象实现了 forwardingTargetForSelector: 方法,系统会调用该方法来询问对象是否希望将该方法调用转发给另一个对象。
  3. 如果对象返回了一个非空的对象,系统会将该方法调用转发给该对象。
  4. 如果对象返回了 nil,系统会检查该对象是否实现了 methodSignatureForSelector: 方法。
  5. 如果对象实现了 methodSignatureForSelector: 方法,系统会调用该方法来获取该方法的签名。
  6. 如果对象返回了一个非空的方法签名,系统会尝试动态解析该方法。
  7. 如果动态解析成功,系统会调用该方法。
  8. 如果动态解析失败,系统会向该对象发送一个 doesNotRecognizeSelector: 消息。

慢速查找流程的代码示例

- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL selector = [invocation selector];
    if ([self respondsToSelector:selector]) {
        [invocation invokeWithTarget:self];
    } else {
        [super forwardInvocation:invocation];
    }
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature *signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        signature = [NSMethodSignature signatureWithObjCTypes:"@@:"];
    }
    return signature;
}

结语

通过对 iOS 中方法的慢速查找流程的介绍,我们对 iOS 的运行时机制有了更深入的了解。这些机制使 iOS 能够在运行时动态地查找和调用方法,从而提高了程序的灵活性