Associated Objects 小记
栏目: Objective-C · 发布时间: 7年前
内容简介:Associated Objects 小记
在一个 viewController 的生命周期内,只执行一次某段代码,怎么做?
第一种方法是最常见也是最简单的方法,加标记位。
还有没有更优雅的办法呢?面向 Google 编程,得到这个答案:
void (^excuteOnce)() = ^{ if (objc_getAssociatedObject(self, _cmd)) { return; } objc_setAssociatedObject(self, _cmd, @"Launched", OBJC_ASSOCIATION_RETAIN); // some code }; excuteOnce();
什么是 Associated Objects
?
OC 有一个最大的弊端就是,我们可以通过 Category 给一个现有的类添加属性,但不能添加实例变量。不过还好有 runtime
,我们可以通过 Associated Objects
达到这一目的。
通过查看 <objc/runtime.h>
发现, 有三个相关的函数:
-
objc setAssociatedObject(id object, const void *key, id value, objc AssociationPolicy policy)
用于给对象添加关联对象,传入
nil
则可以移除已有的关联对象; -
objc_getAssociatedObject(id object, const void *key)
用于获取关联对象;
-
objc_removeAssociatedObjects(id object)
用于移除一个对象的所有关联对象。
Tips: 一般情况下最好不要用 objc_removeAssociatedObjects
这个函数,它会移除掉一个对象所有的关联对象。所以当我们只想移除某一个关联对象的时候,更好的方法应该是,通过 objc_setAssociatedObject
将它设置为 nil。
关联策略
Behavior | @property Equivalent | Description |
---|---|---|
OBJC_ASSOCIATION_ASSIGN | @property (assign) @property (unsafe_unretained) | 指定一个关联对象的弱引用 |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | @property (nonatomic, strong) | 指定一个关联对象的强引用,不能被原子化使用 |
OBJC_ASSOCIATION_COPY_NONATOMIC | @property (nonatomic, copy) | 指定一个关联对象的copy引用,不能被原子化使用 |
OBJC_ASSOCIATION_RETAIN | @property (atomic, strong) | 指定一个关联对象的强引用,能被原子化使用 |
OBJC_ASSOCIATION_COPY | @property (atomic, copy) | 指定一个关联对象的copy引用,能被原子化使用 |
使用场景
根据 Mattt Thompson 大神的总结, Associated Objects
比较好的使用场景有这三种:
-
添加私有属性用于更好地去实现细节。当扩展一个内建类的行为时,保持附加属性的状态可能非常必要。注意以下说的是一种非常教科书式的关联对象的用例:AFNetworking在 UIImageView 的category上用了关联对象来保持一个operation对象,用于从网络上某URL异步地获取一张图片。
-
添加public属性来增强category的功能。有些情况下这种(通过关联对象)让category行为更灵活的做法比在用一个带变量的方法来实现更有意义。在这些情况下,可以用关联对象实现一个一个对外开放的属性。回到上个AFNetworking的例子中的 UIImageView category,它的 imageResponseSerializer方法允许图片通过一个滤镜来显示、或在缓存到硬盘之前改变图片的内容。
-
创建一个用于KVO的关联观察者。当在一个category的实现中使用KVO时,建议用一个自定义的关联对象而不是该对象本身作观察者。ng an associated observer for KVO**. When using KVO in a category implementation, it is recommended that a custom associated-object be used as an observer, rather than the object observing itself.
参考链接
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。