1.什么是分类
分类(Category)是Objective-C 2.0之后添加的语言特性,表示一个指向分类结构体的指针。Category主要作用是为已经存在的类添加新行为(属性、方法、协议)。
2.分类能干什么
分类在原则上只能添加方法,不能添加实例变量 添加实例方法 添加类方法 添加协议 添加属性;只声明了实例变量 并没有 getter和setter
3.分类源码
cd到对应文件夹
xcrun -sdk iphonesimulator clang -rewrite-objc main.m
添加 main.cpp
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
转换成main-arm64.cpp
打开 main-arm64.cpp 搜索 YZAnimal
objc_object
dispatch_object
_method_list_t
类方法和对象方法都会有一个对应的 _method_list_t
_pro_list_t
添加了实例变量
T:类型 @"NSString": 变量类型为NSString C: copy N: nonatomic
由于 @property = ivar + getter + setter 但是在结构体中的属性列表里并没有 getter和setter,所以添加属性值是声明了实例变量。
这个时候就需要使用到关联对象
4.关联对象 associatedObject
顾名思义,就是吧一个对象关联到另一个对象上,使两者产生联系。 分类通过objc_setAssociatedObject 和 objc_getAssociatedObject 方法来设置和获取关联对象。
4.1 关联对象的底层结构
graph TD
HashMap --> AssociatedObjectMap --> AssociatedObject
HasMap存放对象的地址(key),AssociatedObjectMap(value) HashMap的value是一个Hash表,因为一个对象可能会有多个关联属性
这个AssociatedObjectMap包括了
AssociatedObjectMap存放key值为关联属性对应的key,value是一个结构体AssociatedObject(policy, new_value),这个结构体里面有个成员变量
new_value才是我们关联的具体属性
关联对象就是为了存储值 policy 和 value 这个值会关联到某个对象,这个对象会有多个属性,整个list里面又会有多个对象,多个类多个属性,就会有一个二级映射。 整个内存里只有一张Hash表,一张Hash表关联
4.2 添加关联对象
objc_setAssociatedObject(self, @selector(aCategoryAnimalName), aCategoryAnimalName, OBJC_ASSOCIATION_COPY_NONATOMIC);
objc_getAssociatedObject(self, _cmd);
4.3 删除关联对象
objc_setAssociatedObject(self, @selector(aCategoryAnimalName), nil, OBJC_ASSOCIATION_COPY_NONATOMIC);
不要直接调用objc_removeAssociatedObject
4.4 关联对象如何创建weak属性
5.散列表SideTable
散列表有多张SideTables
每个类都有多个分类么?很少
引用计数表、弱引用表会经常频繁引用发生,所以会出现多张
如果散列表只有一张,频繁开锁解锁,安全性会出现问题,一张表里有所有的对象,性能也会受到影响
单个的关联对象都有一张对应的表 如Name,Age