Objective-C分类面试题
你用分类做哪些事?
声明私有方法
分解体积庞大的类文件
把Framework的私有方法公开化
特点:
运行时决议(编好分类文件之后并没有实时把写好的方法附加到原来的类上,是在运行时的时候动态添加编写完成的方法)
可以为系统类添加分类
分类都可以添加哪些内容?
实例方法
类方法
协议
属性(只声明getter setter方法 没有添加实例变量 关联对象添加实例变量)
分类的源码流程
分类添加实例方法流程:
判断是否元类,获取分类列表(是个数组),声明三个二维数组(数组里面还是数组),方法数组 属性数组 协议数组
倒序遍历分类列表,把所有分类的方法列表加到二维数组里,把类的原有的方法拼接到二维数组后面,然后拷贝给宿主类,
这就是为什么分类方法会覆盖原有方法。
总结:
分类添加的方法可以“覆盖”原类方法
同名分类方法谁能生效取决于编译顺序(最后被编译的分类最优先生效)
名字相同的分类会引起编译报错
分类能添加成员变量吗
能,通过对象关联的方法
//根据key获取关联值
id objc_getAssociatedObject(id object,const void * key) //设定一个值跟key形成映射关系 通过策略关联到对象上(以什么关键字关联对象) void objc_setAssociatedObject(id object,const void *key,id value,objc_AssociationPolicy policy)
//移除关联对象
void objc_removeAssociatedObject(id object)
关联对象实现的为分类添加成员变量,这些成员变量保存在哪?
关联对象由AssociationsManager管理并在AssociationsHashMap存储。
所有对象的关联内容都在同一个全局容器中。
关联对象的本质
ObjectAssociation把关联对象策略和value值打包起来
ObjectAssociationMap把key跟上面的ObjectAssociation映射起来
AssociationsHashMap(全局容器)把被关联对象的指针值跟ObjectAssociationMap映射
最终的结构是
全局容器包含2个类
@selector()是被关联的key
怎么擦除被关联key的值,set_objcAssociation设置value为nil即可