iOS 底层系列 - Category

iOS 底层系列 - Category

IOS小彩虹2021-08-24 17:15:05280A+A-

一、常见问题

1. Category 和 Class Extension 的区别是什么?

  1. 分类 的加载在 运行时,类拓展 的加载在 编译时。不能给类添加成员变量。
  2. 类拓展 只以 声明的形式存在,一般存在 .m 文件中,在 编译期就 已经包含在类信息中 ,对于系统一些类,如nsstring,就 无法添加类扩展。

2. Category 中有 load 方法吗?

有load方法。

  • load方法在runtime加载类、分类的时候调用。
  • load方法可以继承,但是一般情况下不会主动去调用load方法,都是让系统自动调用。

3. Category 可不可以添加实例对象?为什么?

不可以。

  1. Category 的结构体内部没有容纳 Ivar 的数据结构。
  2. class_rw_t 里面没有 ivar, class_ro_t 里面有 ivar 但是是只读的。

4. Category 中的 mememove,memcpy 是做什么的。

  • 这俩方法是位移、复制
  • 简单理解就是 原有的方法移动到最后,根根新开辟的控件,把前面的位置留给分类,然后分类中的方法,按照倒序依次插入可以得出的结论就就是,越晚参与编译的分类,里面的方法才是生效的那个。

5、Category +load 方法调用顺序,与相同方法的调用顺序

(1)方法调用的生效

后编译的类中方法生效,分类 方法调用 大于类。 分类方法会覆盖类。

如下图:

(2)Load调用的顺序

先编译的生效,类 load 的调用顺序 大于分类load。 顺序:父类 -》当前类-》分类

如下图:

6. Category 在编译过后,是在什么时机与原有的类合并到一起的?

  1. 程序启动后,通过编译之后,Runtime 会进行初始化,调用 _objc_init

  2. 然后会 map_images

  3. 接下来调用 map_images_nolock

  4. 再然后就是 read_images,这个方法会读取所有的类的相关信息。

  5. 最后是调用 reMethodizeClass:,这个方法是重新方法化的意思。

  6. reMethodizeClass: 方法内部会调用 attachCategories: ,这个方法会传入 Class 和 Category ,会将方法列表,协议列表等与原有的类合并。最后 加入到 class_rw_t 结构体中。

二、Category 分类

1. Category 实现原理

  1. Category 编译之后的底层结构是 struct category_t 结构体,里面存储着分类的对象方法、类方法、属性、协议信息.
  2. 在程序运行的时候,runtime 会将Category的数据,合并到类信息中(类对象、元类对象中)
  3. Category 的生效是按照最后编译的,合并方法后分类方法覆盖到原有类前面。

2. Category 底层结构

3. 分类的加载过程

  1. 对象创建后 _objc_init - map_2_images - map_images_nolock - _read_images
  2. _read_images 中 获取所有类中对应的分类列表。
void _objc_init(void)
    └──const char *map_2_images(…)
        └──const char *map_images_nolock(…)
            └──void _read_images(header_info **hList, uint32_t hCount)

_objc_init

  • 算是整个 objc4 的入口,进行了一些初始化操作,注册了镜像状态改变时的回调函数

map_2_images

  • 主要是加锁并调用 map_images_nolock

map_images_nolock

  • 在这个函数中,完成所有 class 的注册、fixup等工作,还有初始化自动释放池、初始化 side table 等工作并在函数后端调用了 _read_images

_read_images

  • 方法干了很多苦力活,比如加载类、Protocol、Category,加载分类的代码就写在 _read_images 函数的尾部

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们