美文网首页
Runtime应用系列:关联对象

Runtime应用系列:关联对象

作者: 羊非鱼丶 | 来源:发表于2018-07-26 15:31 被阅读0次

AssociatedObject

对象实例化后不能动态添加属性,除非在动态创建一个类时。如果想给一个已经存在的对象添加属性,就需要通过关联对象(Associated Object)实现这个需求。关联对象相当于把一个对象关联到另外一个对象上。在关联后可以随时获取该关联的对象,在对象销毁时会移除所有关联的对象。而在Category当中,正常情况下为其添加属性会报错,因为它不会自动生成settergetter,所以就需要使用关联对象来为其实现添加的属性。

  • 为实例化后的对象动态添加属性
#import "ViewController.h"
#import "MyClass.h"
#import <objc/runtime.h>
@interface ViewController ()

@end

static const void *kAssociatedKey = &kAssociatedKey;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    MyClass *myClass = [[MyClass alloc] init];
    
    objc_setAssociatedObject(myClass, kAssociatedKey, @"associatedObject", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    NSString *assciatedString2 = objc_getAssociatedObject(myClass, kAssociatedKey);
    NSLog(@"关联后的结果:%@",assciatedString2);
}

打印出的结果:


Xnip2018-07-26_15-15-53
  • Category添加属性

.h文件:

@interface UIViewController (MyVC)
@property (nonatomic, strong) NSString *associatedString;

@end

.m文件

#import "UIViewController+MyVC.h"
#import <objc/runtime.h>

static const void *kAssociatedKey = &kAssociatedKey;

@implementation UIViewController (MyVC)
-(void)setAssociatedString:(NSString *)associatedString {
    objc_setAssociatedObject(self, kAssociatedKey, associatedString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)associatedString {
    return objc_getAssociatedObject(self, kAssociatedKey);
}

@end

调用及结果:

#import "ViewController.h"
#import "UIViewController+MyVC.h"
@interface ViewController ()
@end

static const void *kAssociatedKey = &kAssociatedKey;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.associatedString = @"category";
    NSLog(@"%@", self.associatedString);    
}

Xnip2018-07-26_15-19-27

大道同宗,通过objc_setAssociatedObject给对象关联一个字符串(属性),再通过objc_getAssociatedObject获取关联的值。其中objc_setAssociatedObject的四个参数分别为原关联对象、关联属性key、关联属性和关联策略,第二个参数key要保持唯一性,一般写法有以下三种:

  • 声明static void *kAssociatedKey,将&kAssociatedKey作为key
  • 声明static const void *kAssociatedKey = &kAssociatedKey,将&kAssociatedKey作为key
  • selector作为key

最后一个参数objc_AssociationPolicy用于指定关联的策略,用法参考官方文档中的说明。

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

相关文章

网友评论

      本文标题:Runtime应用系列:关联对象

      本文链接:https://www.haomeiwen.com/subject/ruybmftx.html