美文网首页
iOS Runtime详解之SEL,Class,id,IMP,_

iOS Runtime详解之SEL,Class,id,IMP,_

作者: 大风天上来 | 来源:发表于2019-06-20 18:02 被阅读0次

什么是runtime?

Objective C语言把能在运行期做的事情就推迟到运行期再决定。这就意味着,Objective C不仅需要一个编译器,而且需要一个运行期环境。这个运行期环境就是Runtime。

最直接的例子就是方法调用
这样的一个OC方法

[receiver message]

会被编译成

objc_msgSend(receiver, selector)

这里,先记着receiver就是接受消息的对象,selector是执行消息的函数体名称,是个C的字符串。而不是像其他语言一样,直接编译成一个指向函数体的指针。

那么,在运行的时候,如何通过objc_msgSend(receiver, selector)找到实际的函数体呢?

SEL/objc_selector

  • objc_selector
    透明的数据结构,可以理解为C String

  • SEL
    源代码定义

typedef struct objc_selector *SEL;

也就是说,SEL是指向一个C String的指针。

id/objc_object

  • id
    指向一个类的实例对象
    底层代码定义
typedef struct objc_object *id;

其中

  • objc_object
    底层定义
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

可以看到,objc_object中,只是保存了一个Class类型的isa。这里看不懂不要怕,先记着,对象中就是保存了一个指向Objective C中对应类的指针。

Class/objc_class

  • Class
    指向Objective C类对象(objc_class)的一个指针
    底层定义
typedef struct objc_class *Class;
  • objc_class
    底层定义
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

可以看到,这就是类对象结构体的定义,细心的同学可能发现了类对象里仍然有一个指针Class isa,先记着,这个isa指向的是类元对象。这个我会在下一篇文章里详细阐述

IMP

  • IMP-指向实际执行函数体的函数指针
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
#else
typedef id (*IMP)(id, SEL, ...); 
#endif

可以看到,这个函数体前两个参数是 id(消息接受者,也就是对象),以及SEL(方法的名字)

method/objc_method

  • method - 指向Objective C中的方法的指针
typedef struct objc_method *Method;

其中

struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;

_cmd

SEL 类型的一个变量,Objective C的函数的前两个隐藏参数为self 和 _cmd

Ivar

  • ivar - objective C中的实例变量
typedef struct objc_ivar *Ivar;

可以看到变量的内存模型

struct objc_ivar {
    char *ivar_name                                          OBJC2_UNAVAILABLE;
    char *ivar_type                                          OBJC2_UNAVAILABLE;
    int ivar_offset                                          OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
}                                                            OBJC2_UNAVAILABLE;

这篇文件是转载过来,后续重新编辑。


作者:黄文臣
来源:CSDN
原文:https://blog.csdn.net/Hello_Hwc/article/details/49682857
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章

网友评论

      本文标题:iOS Runtime详解之SEL,Class,id,IMP,_

      本文链接:https://www.haomeiwen.com/subject/jbmjqctx.html