推荐阅读:关于iOS面试题汇总(栏目持续更新)
一、常见问题
1. Category 和 Class Extension 的区别是什么?
- 分类 的加载在 运行时,类拓展 的加载在 编译时。不能给类添加成员变量。
- 类拓展 只以 声明的形式存在,一般存在 .m 文件中,在 编译期就 已经包含在类信息中 ,对于系统一些类,如nsstring,就 无法添加类扩展。
2. Category 中有 load 方法吗?
有load方法。
- load方法在runtime加载类、分类的时候调用。
- load方法可以继承,但是一般情况下不会主动去调用load方法,都是让系统自动调用。
3. Category 可不可以添加实例对象?为什么?
不可以。
- Category 的结构体内部没有容纳 Ivar 的数据结构。
- class_rw_t 里面没有 ivar, class_ro_t 里面有 ivar 但是是只读的。
4. Category 中的 mememove,memcpy 是做什么的。
- 这俩方法是位移、复制
- 简单理解就是 原有的方法移动到最后,根根新开辟的控件,把前面的位置留给分类,然后分类中的方法,按照倒序依次插入可以得出的结论就就是,越晚参与编译的分类,里面的方法才是生效的那个。
5、Category +load 方法调用顺序,与相同方法的调用顺序
(1)方法调用的生效
后编译的类中方法生效,分类 方法调用 大于类。 分类方***覆盖类。
如下图: image
(2)Load调用的顺序
先编译的生效,类 load 的调用顺序 大于分类load。 顺序:父类 -》当前类-》分类
如下图: image
6. Category 在编译过后,是在什么时机与原有的类合并到一起的?
程序启动后,通过编译之后,Runtime 会进行初始化,调用
_objc_init
。然后会
map_images
。接下来调用
map_images_nolock
。再然后就是
read_images
,这个方***读取所有的类的相关信息。最后是调用
reMethodizeClass:
,这个方法是重新方法化的意思。在
reMethodizeClass:
方法内部会调用attachCategories:
,这个方***传入 Class 和 Category ,会将方法列表,协议列表等与原有的类合并。最后加入到 class_rw_t
结构体中。
二、Category 分类
1. Category 实现原理
- Category 编译之后的底层结构是 struct category_t 结构体,里面存储着分类的对象方法、类方法、属性、协议信息.
- 在程序运行的时候,runtime 会将Category的数据,合并到类信息中(类对象、元类对象中)
- Category 的生效是按照最后编译的,合并方法后分类方法覆盖到原有类前面。
2. Category 底层结构
image
3. 分类的加载过程
image
- 对象创建后 _objc_init - map_2_images - map_images_nolock - _read_images
- _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