面试题:关于类拓展 && 分类添加属性&&load调用时间&&initialize调用时间

226 阅读2分钟

摘要:

面试题:

  1. 类拓展和分类
  2. 用关联对象给分类添加属性
  3. load的调用时间
  4. 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