美文网首页
runtime之理解“类”

runtime之理解“类”

作者: 凉秋落尘 | 来源:发表于2019-10-16 13:56 被阅读0次

OC是一门动态运行时的语言,为了能够高效运作,不仅需要一个编译器,也需要一个运行时系统来动态得创建类和对象、进行消息传递和转发。对runtime机制的理解,除了能深入了解系统的核心内容以外,也可以在项目中更好的去扩展以更高效的实现。

OC并不能直接编译为汇编语言,而是要先转写为纯C语言再进行编译和汇编的操作,从OC到C语言的过渡就是由runtime来实现的。然而我们使用OC进行面向对象开发,而C语言更多的是面向过程开发,这就需要将面向对象的类转变为面向过程的结构体。

因此理解runtime的原理不仅能帮助去学习runtime,也能去帮助我们更深入的了解OC对象的实现。接下来我们就来了解一下OC一些对象的组成和原理:

类的理解

objc_class 类对象

在OC中我们使用类,但是都是封装成类名,那么对象(object),类(class)底层是怎么封装的?

我们可以查找Class的定义,可以看到它是个objc_class类型的对象,而objc_class则是C语言中的结构体。

typedef struct objc_class *Class;
struct objc_class {
    Class _Nonnull isa;

#if !__OBJC2__
  // 父类
    Class _Nullable super_class;
 // 类名
    const char * _Nonnull name;
// 版本
    long version;
// 其他信息
    long info;
// 实例方法大小
    long instance_size;
// 属性列表
    struct objc_ivar_list * _Nullable ivars ;
// 方法列表
    struct objc_method_list * _Nullable * _Nullable methodLists;
// 缓存对象
    struct objc_cache * _Nonnull cache;
// 协议列表
    struct objc_protocol_list * _Nullable protocols ;
#endif

} OBJC2_UNAVAILABLE;

类对象就是一个结构体,这个结构体存放的数据称为元数据(metadata),,objc_class中包含所定义的属性,方法,协议。同时还有为了优化运行时的效率而定义的缓存cache,所属的父类super_class的Class,以及该类的isa指针。

objc_object 实例对象

我们通过一个类创建一个对象,这个对象本身也是一个结构体objc_object,该结构体是指向Class的isa指针:

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

说明类创建的对象本质是一个指向Class的指针对象。

isa指针和元类(Meta Class)

类对象中的元数据存储的都是如何创建一个实例的相关信息,那么类对象和类方法应该从哪里创建呢?就是从isa指针指向的结构体创建,类对象的isa指针指向的我们称之为元类(metaclass)

objc_class也是一个对象,在objc_objectobjc_class中我们看到都定义了isa指针,找到其继承通过isa指针。objc_object指向的是objc_class,而objc_class指向的元类类的Meta Class同时通过super_class指向的父类的super_class

这样的一个流程可以从子类对象根据isasuperClass层层找到元类(metaclass),因此isa是指向元类,通过superClass指针指向父类,通过这种方法可以去建立层次关系。

例如,定义一个NSString对象:

NSString *str = @"name";

其通过isa指针和superClass参数建立的指向关系:
NSString对象->NSString类对象->NString元类->NSObject元类
NSString对象->NSString类对象->NSObject类对象(superClass)->通过isa指向NSObject元类

class关系图.png
如上图所示,相对于isa对象指向ClassClass指向metaClass;相对于superClassClass指向superClass。这样superClassisa指向也supermetaClass;最终指向rootMetaClass
objc_method_list

每个Class都有对应的cachemethodLists,当调用方法时,通过这两者,找到对应的目标objc_method执行过程。其中objc_method包括:选择子、方法类型、IMP指针。objc_ cache而缓存的目的是为了优化再次调用方法时,可以直接获取。

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

struct objc_method_list {
    struct objc_method_list * obsolete;

    int method_count;
#ifdef __LP64__
    int space
#endif
    struct objc_method method_list[1];
};

前篇讲过消息传递的过程,当对象调用消息时:
先判断接收者(receiver)是否为nil
再通过对象isa指针找到所属Class
查找对应的cache,如果有存在该选择子(SEL)的objc_method对象,转发IMP返回的值;
如果cache不存在,去查找该ClassmethodLists列表,找到存入cache中,并执行IMP
如果methodLists也不存在,通过super_class查找父类,与前面一样查找父类的cachemethodLists如果都没有找到,就执行消息转发。

相关文章

  • runtime之理解“类”

    OC是一门动态运行时的语言,为了能够高效运作,不仅需要一个编译器,也需要一个运行时系统来动态得创建类和对象、进行消...

  • iOS runtime笔记一

    参考资料 南峰子的runtime 一【OC刨根问底】Runtime简单粗暴理解 对象的理解,元类(meta cla...

  • XAURLComponents-在低版本可以直接使用NSURLC

    深入理解Objective-C的Runtime机制 黑魔法——“低版本中使用高版本中出现的类”之技术实现原理详解 ...

  • iOS开发 Runtime 流程图

    你了解多少Runtime? isa 指针的理解 实例对象 isa 指向类对象 类对象指 isa 向元类对象 元类对...

  • runtime中元类的理解

    参考文章 清晰理解Objective-C元类object_getClass(obj)与[obj class]的区别...

  • Runtime之对象,类

    对象 我们知道对象是某个类的实例,并且这个对象的isa指针指向它所属的类。来看一下它的定义,实际上是一个objc_...

  • Runtime 与 Aspects

    Runtime 之 isa指针 1.横向看:实例是对象,类也是对象(类对象),meta类也是对象(原类对象)这是很...

  • OC -> Runtime

    Runtime简介 Runtime用处 Runtime实践 Runtime 类方法调用实现。Person * p ...

  • iOS runtime(三)runtime之method(1)m

    iOS runtime(一)runtime之Property 详尽iOS runtime(二)runtime之Iv...

  • runtime02-常用API

    runtime常用API runtime API01-类相关 runtime API01-类相关-事例01 run...

网友评论

      本文标题:runtime之理解“类”

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