美文网首页
NSObject本质

NSObject本质

作者: 分流替躺欧阳克 | 来源:发表于2019-05-31 21:09 被阅读0次

1:结构

1:NSObject在内存中的大小:

系统分配给NSObject实例对象16个字节,但是对象只用了8个字节.

2:OC 对象分三类:实例对象(instance)、类对象(Class)、元类对象(MetaClass).

instance:存放了isa、成员变量值。

Class:isa,superCalss,cache_t, class_data_bits_t四个成员。

MetaClass:  结构和类对象一致,只是它存的数据比类对象少,存了类对象方法,isa,superClass。其他很多地方都是nil。

2 成员具体内容

1 class_data_bits_t

class_data_bits_t&FAST_DATA_MASK获取的class_rw_t  中存了成员方法列表,属性列表,协议列表,flags,version等一些信息。这三个列表是二维数组(数组的成员是每个类的所有分类的一位数组方法列表,属性列表,协议列表)。

class_ro_t 中也存了方法列表,协议列表, 属性列表。但是这个结构体里的列表都是一维数组,在运行时,会将一个类的所有,分类,协议,属性重新规划,并且class_ro_t是不可读的。具体见 图-01。

图-01

值得注意的是class_data_bits_t一开始也是指向class_ro_t,在运行时,合并分类的时候,才将class_data_bits_t指向class_ro_t.

2 isa和superClass与类的关系

实例对象isa指向类对象,类对象isa指向元类对象,所有的元类对象isa指向基类的元类(报括基类的isa,指向自己)。

实例对象没有superClass,类对象superClass指向其父类,基类的superClass指向基类的类对象([NSObject class]).基类的superClass =nil;。

#  define ISA_MASK        0x00007ffffffffff8ULL

这里的isa是指arm64之前的,若是arm64之后,则需要把isa &ISA_MASK,取出其中一段才是我们之前概念里面的isa指针。因为arm64之后,苹果有优化,Class isa 变成了 isa_t这个union公用体,里面不止是存了类对象,元类对象的地址,还存着有其他许多信息,比如nonpointer代表,bits里有一个bit代表这个isa是否是普通指针

图-02

3 cache_t

cache_t:调用过的方法列表。结构体里存着三个成员:struct bucket_t *_buckets//散列表、mask_t _mask;//散列表的长度-1 、ma s k_t  _occupied;//已经缓存的方法数量。_bucket 里存两个成员:cache_key_t key;//SEL作为key   IMP _imp //函数的内存地址。如 图-02:

图-03

往cache_t里存方法过程:

用方法的SEL(_key),即@selector(方法名)&_mask 得到一个索引,然后看buckets对应索引的位置有没有方法,没有的话,_key = @selector(方法名), _imp = 函数地址组成一个bucket存到对应索引的位置。若是一开始对应索引已经存值了,把索引-1,把bucket存到这里。若是每个索引位置都有bucket存着,则清空 buckets, mask_t乘以2,把bucket存到对应索引位置。

从cache_t里取方法过程:

用方法的SEL(_key),即@selector(方法名)&_mask 得到一个索引,然后根据索引从_buckets散列表里取出一个_bucket,把_bucket里的_key 和 @selector(方法名)对比,若是相等则返回方法,若是不相等则,把索引减1,往前查找,一直查到0,若是还找不到,则跳到最后,一直找到之前索引位置+1.还没有则返回null。

散列表(哈希表):用某种算法获取值当成索引获取value,存取数据,空间换时间。

查找方法过程:

先去一个类的cache_t里去查找,如果找不到则去methods方法列表里去找,找到的话就往cache_t里存,如果找不到,则通过superCalss指针找到它的父类,在父类里的cache_t里找,找不到则去方法列表里找,找到的话,往子类的cache_t里存(注意是自己的cache_t)。再找不到则通过父类的superCalss里去找,一直找到基类或者抛出异常。

class_data_bits_t & FAST_DATA_MASK 可以获得 图-04内容,其中methods是二维数组,存着许多method_list_t(一维数组),每个method_list_t可能是一个分类的所有方法的数组。或者类本身方法数组。method_list_t里存着许多个method_t,里面内容如图-05:

图-04

另:method结构

图-05

属性列表和协议列表与之类似。

注SEl :当作方法名方法序列号,里面首元素为char类型,因为把它的地址转成char就是字符串,结构体地址即是首元素地址。 

内容仅供自己记录学习内容。

相关文章

  • NSObject 底层本质

    NSObject 底层本质 NSObject 底层本质

  • NSObject本质

    1:结构 1:NSObject在内存中的大小: 系统分配给NSObject实例对象16个字节,但是对象只用了8个字...

  • NSObject 底层本质

    一、OC 转 C/C++ 二、NSObject 对象内存布局 三、NSObject 内存大小 四、OC 对象内存布...

  • NSObject的本质

    NSObject是所有类的基类,所有的类都继承自它,它太平常了,平常到我们从不去多加任何思考,但是它又那么重要,因...

  • 对象的本质 Class结构 + load + initializ

    对象的本质 NSObject * obj = [[NSObject alloc] init];转化成c++可以到本...

  • OC底层基础:面试题

    一、NSObject本质 一个NSObject对象占用多少内存(16)系统分配了16个字节给NSObject对象(...

  • 2018-07-03

    NSObject的内存本质 1.实例化一个NSObject对象 (arm64位系统情况下) NSObject *o...

  • OC对象的内存:一个NSObject对象占多少内存?

    问:一个NSObject对象占多少内存? 答:NSObject 对象占16个字节的内存。NSObject本质上一个...

  • NSObject本质(四)NSObject对象的分类

    前面几篇文章主要讲解了NSObject实例对象在内存中如何分布,但是我们都知道一个类中,肯定不止存在成员变量,还有...

  • Block总结

    一、Block的底层结构及本质 (1)block本质: 从代码可以看出,Block的本质就是NSObject. 也...

网友评论

      本文标题:NSObject本质

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