美文网首页
OC类结构分析

OC类结构分析

作者: Johnny_Wu | 来源:发表于2021-06-18 22:44 被阅读0次

一、概要

先要区分两个概念:
1、类:一种结构体,所有对象公用一个类结构。
2、对象:通过类创建出来,每个对象有独立的内存空间。

Student *obj = [[Student alloc] init];
obj就是对象
Student就是类

二、对象结构

截屏2021-06-18 下午9.46.06.png

如上图,Student对象实例stu结构为Student_IMPL,定义的所有成员变量,属性都会包含在对象结构体中。这样就能确保所有对象的成员变量和属性都是独立的,相互不影响。

大家会发现,对象结构体里没有方法?
方法比较特殊,不像成员变量,方法可以所有对象公用一个方法,只需要在方法参数传入对象的本身的指针self,就可以区分是哪个对象在使用方法了。
那么,方法存到哪里呢?这里就引入了类结构。

三、类结构

Class ging.png

objc_class就是类的结构,通过结构里面的bits可以找到另一个结构class_rw_t和class_ro_t。

1、先看看class_rw_t和class_ro_t主要的内容:

class_ro_t!frfubaseMethodList. basePl, ivas, bapr21ERIWL,&HOMIÑA.png
截屏2021-06-18 下午9.59.55.png

class_ro_t是类初始时候的东西,比如方法是放到baseMethodList
如果增加了分类,就会把分类方法放到class_rw_t的methods里面,并且把baseMethodList拷贝到methods的后面。这就解释了添加分类方法后,原同名的方法不是被覆盖的,而是被放到了分类的后面,导致每次都是只找到分类的方法。

2、method_t结构:

截屏2021-06-18 下午10.04.09.png

这里重点看看types:

截屏2021-06-18 下午10.05.20.png
oc的函数,默认会传入两个值,id和sel类型
i ->返回值
@ ->传入的第一个参数,id类型
: ->传入的第二个参数,sel类型
i ->传入的第三个参数,int类型
f ->传入的第三个参数,float类型
返回值i24代表,一共有24个字节。
其他的每个标识后面跟的数字代表从第几个字节开始。如 @0,代表 id参数从第0个字节开始。
更多类型参考:
截屏2021-06-18 下午10.13.10.png

3、objc_class
3.1、isa指针
下面,我们回来看看基本类结构objc_class。
isa指针,对象的isa指向类,类的指向元类。
arm64以前的,isa占8个字节,直接指向类或元类
arm64以后,isa使用共同体的方式,其中指向类或元类的地址指针为isa&mask得到,一个33位+后面3个0=36位。所以所有对象的地址后三位都是0。

截屏2021-06-18 下午10.16.53.png

3.2、superclass
比较容易理解,指向父类。下图是isa与superclass的关系:


image.png

对象调用方法的流程:


截屏2021-06-18 下午10.19.30.png
类调用方法的流程:
截屏2021-06-18 下午10.20.06.png

3.3、cache_t


截屏2021-06-18 下午10.22.52.png

通过散列表来缓存已经访问过的方法,以提高访问效率:
存:调用一个方法SEL(test)后,会直接通过一个哈希函数,把SEl(test)转换为对应buckets的idx。这里是直接SEL(test)&mask,任何&mask的值小于等于mask,如果冲突,就idx-1&mask的值。找到idx,就把此方法封装为bucket_t,如果存到buckets列表对应索引idx的位置。
找:查找SEL(test)方法,与上面类似,直接通过哈希函数得到函数对应的idx,然后直接就能找到对应的bucket了,然后再在bucket中找到对应函数的实现imp。

四、一些使用工具

1、将oc代码转为c/c++代码:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件

2、查看工具:


截屏2021-06-18 下午10.37.13.png

下面看个题目:

@interface Student : NSObject
{
    @public
    int _anum;
    int _bnum;
}
@property(nonatomic) int score;
- (void)showName;
@end

Student *obj = [[Student alloc] init];
obj->_anum = 10;
obj->_bnum = 11;
NSLog(@"instandsize=%zi mallocsize=%zi",class_getInstanceSize(obj.class),malloc_size((__bridge void *)obj));

class_getInstanceSize-->24
malloc_size--->32

class_getInstanceSize代表对象占用的内存,已最大字节对齐,因为isa指针为8个字节,所以是8的倍速。

malloc_size代表实际分配了多少的内存来存储这个对象。以16字节对齐。

相关文章

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

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

  • OC 类&类结构分析

    OC底层原理学习 学习OC时,常听的就是万物皆对象,对象都有isa指针,那为什么有isa指针,isa指针到底是谁创...

  • OC类结构分析

    类Class ,也可以称为类对象,在编译时会转成objc_class, objc_class继承自objc_obj...

  • OC类结构分析

    OC是一门面向对象语言,面向对象离不开对象,类,继承,类方法,实例方法,属性,实例变量,对于习惯了面向对象的同学来...

  • OC类结构分析

    一、概要 先要区分两个概念:1、类:一种结构体,所有对象公用一个类结构。2、对象:通过类创建出来,每个对象有独立的...

  • OC 类的结构分析

    网络中有个关于类的关系的图 图中虚线部分是isa的的继承关系证明如下图 有关lldb指令的说明: p/x 以16进...

  • OC底层_类结构分析

    类和类结构分析 类的分析 元类 在如下代码中断点调试: 元类是系统给的,其定义和创建都是由编译器完成,在这个过程中...

  • OC中类结构分析

    想要分析OC中类的结构,我们可以通过clang命令得到底层的实现:clang -rewrite-objc main...

  • 类结构之cache分析

    背景 前面我们在分析ios类结构过程,在oc类结构那点事(四)中我们了解到class有几个关键属性,其中bits信...

  • OC底层原理06-cache_t探究

    iOS--OC底层原理文章汇总 前言 本文主要探索cache_t * cache结构内容,分析它在类的结构中扮演了...

网友评论

      本文标题:OC类结构分析

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