objc_msgsend学习

type
status
date
slug
tags
summary
category
icon
password
id 是一种动态类型,表示一个指向任何对象的指针。
  • 特点:
    • 动态性:在编译时不知道具体的类类型,只有在运行时才知道。
    • 方便:允许编写更加通用和灵活的代码,可以指向任何对象,而不需要显式声明类型。
    • 安全性:由于 id 类型的动态性,编译器不能在编译时检查类型安全,可能会导致运行时错误。
SEL 是一个数据类型,表示一个选择器(selector),即方法的名称。
  • 特点:
    • 方法标识符:选择器本质上是方法的唯一标识符,可以用来动态调用方法。
    • 高效性:选择器通常是由编译器生成的独一无二的标识符,查找速度快。
    • 动态调用:配合 @selector 语法和 NSSelectorFromString 函数,可以在运行时动态调用方法。

idSEL 的应用

  • 动态方法调用: id 类型可以指向任何对象,而 SEL 类型可以表示任何方法,这使得动态方法调用成为可能。
    • 消息转发机制: 在 Objective-C 中,如果一个对象接收到一个它无法响应的消息,它会将该消息转发给其他对象,这个过程会涉及到 idSEL 类型。
    objc_msgSend 是 Objective-C 运行时最核心的函数之一,用于向对象发送消息(即调用方法)。了解它的参数、使用方法以及返回值对于深入理解 Objective-C 的消息机制至关重要。以下是对 objc_msgSend 的详细解释:

    objc_msgSend 的参数

    • self: 这个参数是接收消息的对象。它是一个指向对象实例的指针。
    • op (selector): 这个参数是一个选择器,表示要调用的方法。它是 SEL 类型,通常由 @selector 语法或者 NSSelectorFromString 函数生成。
    • 可选参数: 从第三个参数开始,是传递给方法的实际参数。根据方法的签名,这些参数的数量和类型可以变化。
     

    示例代码

    假设有一个简单的 Objective-C 类 MyClass,其中有一个方法 - (void)myMethodWithArg:(int)arg;,我们可以用 objc_msgSend 发送消息来调用这个方法。
    1. 定义类和方法:
      1. 使用 objc_msgSend 调用方法:

        objc_msgSend 的返回值

        objc_msgSend 的返回值类型取决于被调用的方法的返回类型。在调用 objc_msgSend 时,必须正确地转换返回值类型。

        示例

        假设我们有一个返回值类型为 int 的方法 - (int)sumWithA:(int)a b:(int)b;
        我们可以使用 objc_msgSend 调用这个方法并获取返回值:

        注意事项

        1. 类型转换: 使用 objc_msgSend 时需要进行正确的类型转换。因为它是一个可变参数函数,并且返回类型不确定,必须根据实际情况进行强制类型转换。
        1. 64位架构: 在64位架构上,objc_msgSend 的一些变体如 objc_msgSend_stret(用于返回结构体)以及 objc_msgSend_fpret(用于返回浮点数)在某些情况下可能需要。
        1. 性能考虑: 虽然 objc_msgSend 提供了强大的动态调用能力,但频繁使用可能会影响性能。在大多数情况下,直接调用方法更高效。

        总结

        objc_msgSend 是 Objective-C 运行时消息传递机制的核心,它通过 id(对象)和 SEL(选择器)来实现动态方法调用。正确理解它的参数、返回值以及使用方法对深入掌握 Objective-C 编程至关重要。在实际开发中,尽量使用编译器提供的语法糖来发送消息,只有在特殊情况下才直接使用 objc_msgSend
         

        执行流程

        • 消息发送
        • 动态方法解析
        • 消息转发
         

        消息发送

        notion image
         
        • 如果是从class_rw_t中查找方法
            1. 已经排序的,二分查找
            1. 没有排序的,遍历查找
        • receiver通过isa指针找到receiverClass
        • receiverClass通过superclass指针找到superClass
         

        动态方法解析

        notion image
        动态解析过后,会重新走“消息发送”的流程
         

        消息转发

        notion image
        如果动态方法解析阶段没有处理,回来到消息转发阶段
        首先来到forwardingTargetForSelector:方法,该方法中可以重新返回一个消息接收者,程序将会重新执行objc_msgSend()方法,此时消息时发送给新的接受者如果forwardingTargetForSelector:方法没有处理,会来到methodSignatureForSelector:方法,该方法可以返回一个方法签名,返回后,程序会继续调用forwardInvocation:方法。如果methodSignatureForSelector:方法也没处理,程序就抛出异常forwardInvocation:方法中,开发者可以自定义任何逻辑以上方法都有对象方法、类方法2个版本(前面可以是加号+,也可以是减号-)
         
         
        上一篇
        lldb积累
        下一篇
        iOS动调入门
        Loading...
        文章列表
        Hi~, I ‘m moyao
        reverse
        pwn
        pentest
        iot
        android
        others
        ctf
        iOS