美文网首页
关于OC类结构的一点片面之见

关于OC类结构的一点片面之见

作者: 深海时代 | 来源:发表于2018-04-23 17:38 被阅读0次

初用简书,请多指教.

用了这么久的类和对象,还不知道它们的实现方法,就觉得很别扭,找了个时间初步的自己看了看.就说一下自己的思路.

先说我一开始就知道的:

我们知道类其实是一个结构体,大概是下面的样子:

网上扒下来的类结构图

struct bucket_t  {

    SEL  key;      //方法名称

    IMP imp;      //方法的实现,imp是一个函数指针类型

};

struct cache_t {

    struct bucket_t *buckets;    //缓存方法的哈希桶数组指针,桶的数量 = mask + 1

    int  mask;        //桶的数量 - 1

    int  occupied;  //桶中已经缓存的方法数量。

};

isa指针 指向本类类对象;

super指针 指向父类类对象;

版本名字内存大小不介绍;

关键下面四个结构体:  属性列表;  方法列表;  缓存列表;  协议列表;

当方法调用时发生如下的事件:

objc_msgSend(someObject,_cmd,parameter); //_cmd=@selector(messageName:)

for  ( someObject->isa.(cache||Method_list)) == _cmd ?return _imp;

messageName(someObject,_cmd,parameter);

someObject 是接收体 _cmd: 是选择子 parameter 是参数表;

但是问题来了,Ivar呢,Method是静态固定结构的呀,Ivar是实时会变的呀,

说Method保存在类结构里我是信的,但Ivar的值肯定是放对象里的,那问题来了,怎么证明呢?

下面的是我自己试验的:(就仅仅讨论变量机制,不是看Ivar的就可以到这里了)

定义两个不相干类

类OBJC_Sub 类OBJC_Sub2 建立类A的对象并为属性赋值 调用方法-更换isa指针-调用方法

这里两个类的方法是一样的,变量也是;

结果一样的

更换过类从属仍然得到相同的结果,可得:变量的值确实存在对象里,完毕,谢谢大家,散了散了.

才怪,IvarList到底放的是什么?放地址也不对,类和对象是一对多的关系,类里存放的信息是无法针对到某个对象的.受某个朋友启发,我做了如下操作:

我把_str和numberString的物理位置换了换

于是:

是不是很神奇

然后我就猜测,类结构中的IvarList是一个存放名字和序号的顺序表;对象里存放属性值的是一个顺序表;对象使用属性的时候,根据属性在顺序表中的位置去自身顺序表查值.

如上:类1的_str的索引是1,那么它对编译器的意义就是类的第二个属性,所以他的调用结果是@"1024";

而在类2里_str的索引变成了0,那么它对编译器的意义就变成了类的第一个属性,所以他访问到了numBerString的值 一串随机中文编码;

_str 这个是没有内存意义的,有内存意义的是他的属性序号,就是编译器记住的他的位置;

于是我按照我的猜想又做了一些验证:

类一的属性 类二属性物理倒序 并在类二里输出了属性列表 果然属性也出现了对应倒序 输出了一下两个类的属性

由此可以验证下图模型(其实单链表还是顺序表我很纠结的,因为功能几乎一样,不过这不是重点):

我们天赋画手从来都是忽略细节画灵魂的 设计谋杀图一图二的图三

说结论:

由IvarList到object的映射是通过索引来的,由此我们改变变量位置会影响他对变量地址的判断;

object里顺序排列着变量的地址,这也解释了变量未初始化时的指针保护是怎么实现的(放一个初始指针0x0);

成员属性位于变量末尾,这个的测试我就不多说了,随便一测就能测出来;

值得一提的是类1的变量必须多于类2,因为对象初始化的时候为变量开辟的内存是根据类1来的.如果类1的变量多,切换isa指针后对象变量冗余,OK我访问不到没关系.但是如果类1变量少,切换之后对象变量不足,就会出现野指针报错,虽然你可能不会访问那个野指针,可能ARC会检查这个吧;(野指针见图三)

本来想说说观察者模式来着,可是那个跟方法有关系,故不在讨论之列;

之后还会讨论一下OC 的 NSString、NSArray、NSDictionary,因为他们对象的isa并没有指向本类,这个后面再说;

到这里就完成了,感谢看完的你们.

相关文章

  • 关于OC类结构的一点片面之见

    初用简书,请多指教. 用了这么久的类和对象,还不知道它们的实现方法,就觉得很别扭,找了个时间初步的自己看了看.就说...

  • iOS 类原理探索:类的结构分析

    OC 类原理探索 系列文章 OC 类原理探索:类的结构分析 OC 类原理探索:类结构分析补充[https://ju...

  • Objective-C 中类的数据结构

    一、类的结构 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC 的代码转...

  • 深入理解Objective-C中类的数据结构

    一、类的结构 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC 的代码转...

  • 结构体和类的区别

    一、定义一个结构体 二、使用 三、结构体和OC类的区别 结构体: 只能封装属性,不能封装方法; 分配在栈上 OC类...

  • OC类的结构

    TaggedPointer Tagged Pointer是一个能够提升性能、节省内存的有趣的技术。在OS X 10...

  • 二、 字节对齐

    探索OC类的大小要先来说一下结构体,因为OC类底层都是以结构体的形式存在的。 1 结构体大小-字节对齐 我们先定义...

  • Runtime

    oc对象 OC类对象元类对象编译后的结构如下结构体 isa arm64架构之前isa只是一个指针,指向类对象或者元...

  • Runtime:OC对象、类、元类的本质

    零、Runtime是什么一、OC对象的本质二、OC类的本质三、OC元类的本质四、Runtime关于对象、类、元类的...

  • iOS底层初探

    OC底层实现原理 oc对象以及类的是底层实现 首先,通过数据结构的特性可以猜测类的底层应该是结构体这种数据结构,因...

网友评论

      本文标题:关于OC类结构的一点片面之见

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