这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战
关联属性
准备用一个系统的类,但是系统的类并不能满足当前需求,这时需要额外添加一个属性。这种情况的一般解决办法就是继承。但是,只增加一个属性,就去继承一个类,总是觉得太麻烦类。这时,使用 OC 提供关联属性的功能可以解决此问题
-
给一个对象可以关联一个或多个属性,这些属性通过
key
来区分,每个key
对应一个属性。 -
在给对象关联属性时需要指明属性的特质
关联属性的特质 等效的@property OBJC_ASSOCIATION_ASSIGN
assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC
nonatomic,retain
OBJC_ASSOCIATION_COPY_NONATOMIC
nonatomic,copy
OBJC_ASSOCIATION_RETAIN
retain
OBJC_ASSOCIATION_COPY
copy
-
Runtime 提供了管理关联属性方法(存储、获取、移除):
-
给指定对象设置关联属性
objc_setAssociatedObject(object,key,value, objc_AssociationPolicy policy)
object
:指定对象;
key
:关联的 key,要求唯一,通常为常量;
value
:关联的属性;
objc_AssociationPolicy policy
:关联属性的特质 -
通过给定的
key
从某对象中获取相应的关联属性id objc_getAssociatedObject(object, key)
object
:指定对象;
key
:关联的 key,要求唯一,通常为常量; -
移除指定对象的全部关联属性
objc_removeAssociatedObjects(id object)
object
:指定对象;
注:
objc_removeAssociatedObjects(id object)
函数移除的是某个对象身上的所有关联的对象。objc
没有提供移除object
身上单个关联对象的函数,所以,一般通过objc_setAssociatedObject
函数传入nil
来达到移除某个关联对象的目的。 -
动态添加属性
在 category 中的使用 @property
添加属性,不会生成带下划线的成员变量,也不会有 setter
和 getter
方法实现,所以我们通过 Runtime 关联属性的技术为已经存在的类添加属性,这样只是实现了 setter
和 getter
方法,依然不会有带下划线的成员变量
.h文件
@interface NSString (AddProperty)
@property(copy, nonatomic) NSString *name;
@end
.m文件
#import "NSString+AddProperty.h"
#import <objc/runtime.h>
//定义关联属性的key
static const char *key = "name";
@implementation NSString (AddProperty)
- (NSString *)name{
// 根据关联属性的key,获取关联的值。
return objc_getAssociatedObject(self, key);
}
- (void)setName:(NSString *)name{
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
逻辑处理
#import "ViewController.h"
#import "NSString+AddProperty.h"
- (void)viewDidLoad {
[super viewDidLoad];
//给系统 NSString 类动态添加属性 name
NSString *str = [[NSString alloc]init];
str.name = @"动态添加属性";
NSLog(@"%@",str.name);
}
log:
动态添加属性