AssociatedObject
对象实例化后不能动态添加属性,除非在动态创建一个类时。如果想给一个已经存在的对象添加属性,就需要通过关联对象(Associated Object
)实现这个需求。关联对象相当于把一个对象关联到另外一个对象上。在关联后可以随时获取该关联的对象,在对象销毁时会移除所有关联的对象。而在Category
当中,正常情况下为其添加属性会报错,因为它不会自动生成setter
与getter
,所以就需要使用关联对象来为其实现添加的属性。
- 为实例化后的对象动态添加属性
#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);
}
打印出的结果:
![](https://img.haomeiwen.com/i5277900/cb11f1745dcb2277.png)
- 给
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);
}
![](https://img.haomeiwen.com/i5277900/b7e843c507fda4d5.png)
大道同宗,通过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. */
};
网友评论