iOS给category添加属性之Objective-C Associated Objects

我们知道,在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量。但我们可以通过 Associated Objects 来弥补这一不足。


相关函数

与 Associated Objects 相关的函数主要有三个,我们可以在 runtime 源码的 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_setAssociatedObject用于给对象添加关联对象,传入 nil 则可以移除已有的关联对象;
-objc_getAssociatedObject用于获取关联对象;
-objc_removeAssociatedObjects用于移除一个对象的所有关联对象。

key值

一般来说,有以下三种推荐的 key 值:
1、声明 static char kAssociatedObjectKey; ,使用 &kAssociatedObjectKey作为key 值;
2、声明 static void *kAssociatedObjectKey = &kAssociatedObjectKey;,使用 kAssociatedObjectKey作为 key值;
3、用selector ,使用 getter 方法的名称作为key值。

三种方式看个人习惯都可以。

关联策略

在给一个对象添加关联对象时有五种关联策略可供选择:

关联策略 等价属性 说明
OBJC_ASSOCIATION_ASSIGN @property (assign) 弱引用关联对象
OBJC_ASSOCIATION_RETAIN_NONATOMIC @property (strong, nonatomic) 强引用关联对象,且为非原子操作
OBJC_ASSOCIATION_COPY_NONATOMIC @property (copy, nonatomic) 复制关联对象,且为非原子操作
OBJC_ASSOCIATION_RETAIN @property (strong, atomic) 强引用关联对象,且为原子操作
OBJC_ASSOCIATION_COPY @property (copy, atomic) 复制关联对象,且为原子操作

具体实现

我将演示用3种key值

@interface UIViewController (AssociatedObjects)

@property (strong, nonatomic) NSString *associatedObject_retain;
@property (copy,   nonatomic) NSString *associatedObject_copy;
@property (assign, nonatomic) BOOL associatedObject_assign;

@end
#import "UIViewController+AssociatedObjects.h"
#import "objc/runtime.h"

//声明key值
static char kAssociatedObject_retain_Key;
static void *kAssociatedObject_copy_Key = &kAssociatedObject_copy_Key;

@implementation UIViewController (AssociatedObjects)

- (NSString *)associatedObject_copy {
    
    return objc_getAssociatedObject(self, kAssociatedObject_copy_Key);
}

- (void)setAssociatedObject_copy:(NSString *)associatedObject_copy {
    
    objc_setAssociatedObject(self, kAssociatedObject_copy_Key, associatedObject_copy, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)associatedObject_retain {
    
    return objc_getAssociatedObject(self, &kAssociatedObject_retain_Key);
}

- (void)setAssociatedObject_retain:(NSString *)associatedObject_retain {
    
    objc_setAssociatedObject(self, &kAssociatedObject_retain_Key, associatedObject_retain, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)associatedObject_assign {
    
    return [objc_getAssociatedObject(self, _cmd) boolValue];
}

- (void)setAssociatedObject_assign:(BOOL)associatedObject_assign {
    
    objc_setAssociatedObject(self, @selector(associatedObject_assign), @(associatedObject_assign), OBJC_ASSOCIATION_ASSIGN);
    
}


@end

你可能感兴趣的:(iOS给category添加属性之Objective-C Associated Objects)