Category的底层结构是什么样的?Category的实现原理。
首先,创建个简单的类和对应的分类
通过执行xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc Person+Eat.m -o Person+Eat-arm64.cpp
生成指定的cpp文件可以找到category对应的结构体,其具体结构如下图
通过查看Objective-C源码来进行验证分类的属性、实例方法、类方法和协议信息对应的存放方式,
首先查看objc-os.mm文件,找到对象创建的方法_objc_init
点击进入这个map_images方法
map_images则会调用map_images_nolock
点击进入查看实现方法,找到_read_images方法。
在_read_images方法中,可以找到发现分类这部分代码。
OC的源码已经产生了新的变化,此时是classref_t* classlist数组
点击进入nlclslist会发现两部分,上半部分是类类型的,下半部分是结构体类型的,这部分是临弹性的的分享缓存
list通过两个offset偏移量进行相加后强制转换生成确定大小的数组。
返回之前的_read_images方法找到remapClass方法,点击进去查看,通过cls和map进行判断,如果传入的cls对象不存在则直接返回nil 如果map不存在则直接返回cls对象,迭代器通过通过map映射调用find方法找对应的cls对象,如果迭代器最后map等于map的映射找到了最后,则返回传进来cls对象,最后回到_read_images方法中的遍历调用addClassTableEntry方法,插入到对应的类列表中,所以最终分类的属性、实例方法、类方法、协议信息等重新合并到到对应类中,实现分类的功能。
扩展:分类的load方法会在什么时候调用,再补充个类和分类,进行测试,
可以发现,即使不调用各个类,load的方法就会调用,在类信息加载时load方法就会调用。