标签(空格分隔): iOS category associative
OC的运行时提供了两种机制来对已有的类进行扩展:
- category 对原有的方法进行扩展
- associative 对原有的属性进行扩展
这两者在《Effective Objective-C 2.0》里面都有讲解,分别在第10条和第26条专门做了介绍,这里先介绍两种技术,再说明两者之间的差异化用法。
category 分类
这个OC的机制大家应该很熟悉了,就是对原有类的扩展。《Effective Objective-C 2.0》里面第24,25,26条对category有专门讲解。可以查看专门的这些章节来看下,其中几个要点就是:
- 类的实现代码可以分散到各个分类当中,这样便于整体代码清晰,并且方便调试
- 给分类加上前缀,防止出现命名冲突,这点OC没有C++类似命名空间的机制让人无语,大工程OC命名上就会让人痛苦死。与其这样不如早点将这个问题解决。
- 不要在分类中声明属性,这个后续还会讲解。
associative 关联对象
关联对象平时接触的很少,之前最近看到几个开源库里面都有用到,索性研究透这个,也是极好的。
关联对象的使用场景是在一些无法创建子类的实例,或者在category中想扩展类的属性。这些场景中关联对象就用到了。
要包含头文件才 objc/runtime.h 可以使用关联对象, 关联对象用到的方法主要有:
- void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
以给定的键和策略为某对象设置管理值。 - id objc_getAssociatedObject(id object, const void *key)
- void objc_removeAssociatedObjects(id object)
移除指定对象的全部关联对象。
管理策略(objc_AssociationPolicy)是用以维护对应的“内存管理语义”,是一些枚举值,对应了相应的属性概念:
关联类型 | 等效的@property属性 |
---|---|
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | nonatomic retain/strong |
OBJC_ASSOCIATION_COPY_NONATOMIC | nonatomic copy |
OBJC_ASSOCIATION_RETAIN | retain atomic |
OBJC_ASSOCIATION_COPY | copy |
这篇文章对这个的使用分析的挺好,其中有一点就是key的选取,经常使用_cmd,比如
objc_setAssociatedObject(self, _cmd, cachesByIndexPath, OBJC_ASSOCIATION_RETAIN);
一开始很是不解,但是看到下面这段话:
Since SELs are guaranteed to be unique and constant, you can use _cmd as the key for objc_setAssociatedObject(). #objective-c #snowleopard
明白没?SELS是唯一的,因此可以用_cmd作为key,so tricky!