所有的OC类和对象,在runtime层都是用struct表示的,category也不例外,在runtime层,category用结构体category_t表示
Category可以添加属性,但不会自动生成对应的成员变量及set/get方法实现,只会生成setter/getter的声明。因为category_t结构体中并不存在成员变量。
通过之前对对象的分析我们知道成员变量是存放在实例对象中的,并且编译的那一刻就已经决定好了。
而分类是在运行时才去加载的。那么我们就无法再程序运行时将分类的成员变量中添加到实例对象的结构体中。因此分类中不可以添加成员变量
如果类要添加变量,只有在objc_allocateClassPair与objc_registerClassPair之间addIvar。等类注册后,变量结构就不允许再被改变
objc_removeAssociatedObjects,那么可不可以用这个方法来删除不用的关联对象呢?
苹果的文档中解释说这个方法主要用来还原对象到类初始的状态,会移除所有的关联,包括其他模块添加的,因此应该用 objc_setAssociatedObject(..,nil,..) 的方式去卸载
关联对象的原理
关联对象是Objective-C 2.0运行时的一个特性,AssociationsManager通过一个以指针地址为主键,值为关联表的哈希表,来管理应用内所有的关联对象。
首先以对象的指针地址去寻找关联表,再通过指定的键值查找关联关系,从而获取关联对象。
关联对象的实现不复杂,保存的方式为一个全局的哈希表,存取都通过查询表找到关联来执行。哈希表的特点就是牺牲空间换取时间,所以执行速度也可以保证。
系统如何管理关联对象?
系统通过管理一个全局哈希表,通过对象指针地址和传递的固定参数地址来获取关联对象。
根据setter传入的参数协议,来管理对象的生命周期