摘要:
面试题:
- 类拓展和分类
- 用关联对象给分类添加属性
- load的调用时间
- initialize调用时间
一. 类拓展和分类的区别
区别:类拓展可以添加属性,方法;分类只能添加方法。因为 类拓展在编译时完成加载,数据写入到ro中,而分类在运行时加载,所以数据写入到rw中,没有实现set和get方法,所以无法将属性的值赋值进去,也无法取到。
类拓展在代码实现形式有2种方式,第一种写到所在本类的.m文件中,第二种另一个单写一个.h文件。常用第一种:
编译时间的确定: 在read——images的类的加载中,如下处设置断点,编译时进入断点,查看ro中包含类拓展的属性和实现的get,set方法,可以判断出类拓展在编译时就加载了。而此时类加载后没有分类的信息,由此可以判断分类是在运行时加载进来的。
下图断点信息图:
下图ro中查找信息图:
二.分类中通过关联对象添加属性
在分类的.m文件中,通过调用 objc_setAssociatedObject 和 objc_getAssociatedObject 把新的属性对应的value 存储起来或者取出来。
源码分析流程:
下图中,hashmap中通过对象的指针地址为key取到对应的对象小表,再通过对象的属性key值为下标取到对应key值中对应的value值或者存储value值。 注意:通过key存value时候,如果value为nil,并且之前使用相同的key存储过关联对象,那么就把这个关联的value移除(这也是为什么传入nil对象能够把对象的关联value移除,如果key对应的value查找没到最后一个,替换设置新值,若果到了最后一个则直接设置新值。 如果AssociationsHashMap从没有对象的关联信息表, 那么就创建一个map并通过传入的key把value存进去
三.load的调用时间
load调用分析图:
load调用总结流程图:
四.initialize调用时间
感谢:文章中部分内容引用logic---cooci