问题:使用Runtime Associate 方法关联的对象,需

2020-08-19  本文已影响0人  姜小舟

无论在MRC下还是ARC下均不需要,被关联的对象在生命周期内要比对象本身释放的晚很多,它们会在被 NSObject -dealloc 调用的object_dispose()方法中释放。

关联对象的实现

我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法。

不过,通过 Objective-C 运行时中的关联对象,也就是 Associated Object,我们可以实现上述需求。

#import "DKObject+Category.h"
#import <objc/runtime.h>
 
@implementation DKObject (Category)

- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    // 隐式参数
    // _cmd == @selector(name)
    return objc_getAssociatedObject(self, _cmd);
}
@end

我们使用了两个方法 objc_getAssociatedObject 以及 objc_setAssociatedObject来模拟『属性』的存取方法,而使用关联对象模拟实例变量。
我们从三个 objc 运行时的方法为入口来对关联对象的实现一探究竟,其中两个方法是上一部分使用到的方法:

NSLog(@"以键值对形式添加关联对象")
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
NSLog(@"根据 key 获取关联对象")
id objc_getAssociatedObject(id object, const void *key);
NSLog(@"移除所有关联对象")
void objc_removeAssociatedObjects(id object);

在这里有必要解释两个问题:

关于第一个问题,我们需要看一下这两个方法的原型:

id objc_getAssociatedObject(id object, const void *key);
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

@selector(name) 也就是参数中的 key,其实可以使用静态指针 static void * 类型的参数来代替,不过在这里,笔者强烈推荐使用 @selector(name) 作为 key 传入。因为这种方法省略了声明参数的代码,并且能很好地保证 key 的唯一性。

OBJC_ASSOCIATION_RETAIN_NONATOMIC 又是什么呢?

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,  // 指定一个弱引用相关联的对象
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 指定相关对象的强引用,非原子性
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  // 指定相关的对象被复制,非原子性
    OBJC_ASSOCIATION_RETAIN = 01401,  // 指定相关对象的强引用,原子性
    OBJC_ASSOCIATION_COPY = 01403     // 指定相关的对象被复制,原子性   
};

从这里的注释我们能看到很多东西,也就是说不同的 objc_AssociationPolicy 对应了不通的属性修饰符:

objc_AssociationPolicy modifier
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic, strong
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic, copy
OBJC_ASSOCIATION_RETAIN atomic, strong
OBJC_ASSOCIATION_COPY atomic, copy
上一篇下一篇

猜你喜欢

热点阅读