Category源码分析(最新)

205 阅读2分钟

最近无意中翻看了最新的苹果源码,发现源码的很多实现都跟以前不一样了,抱着对知识探索的渴望,于是决定对Category源码进行分析。

苹果官方源码: github.com/apple-oss-d…

本文只从源码层剖析,Category从程序启动,到最终合并到类对象结构里面的过程。

1. Category内存结构

首先我们先来看看Category的内存结构。

category_t里面存储着 实例方法列表、类方法列表、协议列表、属性列表。

2. Runtime入口

Category是在程序运行时,动态合并到类对象结构中的,所以首先需要找到Runtime的入口,查看是何时加载Category的。

苹果注释写的很清楚,启动初始化,启动dyld,里面有个映射镜像,找到方法map_images的实现。

map_images实现中,调用map_images_nolock,找到它的实现。

map_images_nolock这个方法中,去读镜像。

在读取镜像的过程中,加载Category load_categories_nolock,进去看一看,苹果注释写的很清楚。

苹果这注释写的,感觉都不需要我翻译了,进入attachCategories方法。

methods.attachLists、properties.attachLists、protocols.attachLists 赋值给rwe,rwe是不是很熟悉,没错,他就是类对象里面的class_rw_t,这一步,就是将Category里面的方法列表、属性列表、协议列表,合并到类对象里面的class_rw_t里面去,那我们就看一看它里面是如何合并的,查看attachLists的实现。

attachLists实现其实很简单,将传过来的addedLists(分类数组)、addedCount(数组的个数),新创建个newArray,将原来类的数组,和分类的数组,通过两个for循环,合并到了一起(以前源码是通过两个C语言函数memmove、memcpy合并的,猜测是上面创建的这个分类数组,最大的个数是64,所以数据量是很小的,相对而言,苹果觉得这两个for循环性能更高)

好了,最终Category的方法、属性、协议列表,已经完全合并到类对象的class_rw_t当中去了,那么通过本质可以看出,方法写在Category当中去,和写在类里面,是完全一样的一个效果。

欢迎一起学习交流,不足之处还请指出。