iOS 底层系列 - Category

推荐阅读:关于iOS面试题汇总(栏目持续更新)

一、常见问题

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)方法调用的生效

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

如下图:
image

(2)Load调用的顺序

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

如下图:
image

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 底层结构

image

3. 分类的加载过程

image
  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 函数的尾部

有想要领取免费资料的可以进裙或者加好友领取,这里有一个iOS交流圈:891 488 181 可以来了解,分享BAT,阿里面试题、面试经验,讨论技术,裙里资料直接下载就行, 大家一起交流学习!

有想要的面试资料或者其他资料也可以找我,欢迎咨询!需要的可自行下载




文章到这里就结束了,你也可以私信我及时获取面试相关资料。如果你有什么意见和建议欢迎给我留言。

请iOS的小伙伴关注 !喜欢的话给一个赞吧!谢谢!谢谢!谢谢!

作者:DaSen
链接:https://juejin.im/post/6884627584735248391

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务