iOS 分类Category

632 阅读2分钟

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

image.png

打开 main-arm64.cpp 搜索 YZAnimal

image.png objc_object dispatch_object

_method_list_t

image.png

类方法和对象方法都会有一个对应的 _method_list_t

_pro_list_t

image.png

添加了实例变量

developer.apple.com/library/arc…

developer.apple.com/library/arc…

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表,因为一个对象可能会有多个关联属性

image.png 这个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