一. 为什么要动态添加属性?
思考:当系统提供的类满足不了我们要求的时候, 则需我们手动添加属性,且希望能给系统直接添加属性;
以NSObject为例 (给NSObject 添加一个自定义属性)
- 想法: 1. 创建一个子类继承NSObject, 此时可以添加属性;但是并不是直接给系统的类添加;
- 想法: 2. 给NSObject添加一个分类, 在分类中我们可以实现方法, 但是添加属性, 仅仅只生成方法的声明;并没有方法实现和生成下划线成员变量;
二. 此时考虑使用runtime来动态实现给系统的类添加属性;
tips: 记得区分属性与成员变量
{
NSString *_name; // 成员变量
}
@property (nonatomic, strong)NSString *name; // 成员属性
三. 实现步骤:
1.0 给NSObject 添加一个分类(Property),在里面添加一个自定义属性;
#import <Foundation/Foundation.h>
#import <Foundation/Foundation.h>
@interface NSObject (Property)
@property NSString *name; // 既然没有生成成员变量,那么无需策略进行修饰
@end
2.0 导入runtime的头文件,
3.0 在.h文件中实现name方法的getter 和setter方法
#import "NSObject+Property.h"
#import <objc/message.h>
@implementation NSObject (Property)
- (void)setName:(NSString *)name
{
// 保存name
// 动态添加属性的本质是:让对象的某个属性与值产生关联
objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name
{
// 获取对应属性的值
return objc_getAssociatedObject(self, "name");
}
@end
解析:
// 关联值的方法
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
object:保存到哪个对象中
key:用什么属性保存传入的值
value:需保存值
policy:策略,strong,weak等
// 获取值的方法:
objc_getAssociatedObject(id object, const void *key);
object:从哪个对象中获取值
key: 用什么属性获取值
四.验证: 在其他文件导入NSObject的分类头文件,并使用自定义属性;
NSObject *objc = [[NSObject alloc] init];
objc.name = @"abel";
NSLog(@"%@",objc.name); // 可打印出: abel
题外话:
对于如何记住runtime的方法, 只有一个原则:谁的事情谁处理;故我们可判断runtime方法的前缀是什么.
以本文方法为例, 我们需要给系统添加一个自定义属性;
动态添属性的本质是:让对象的某个属性与值(其他对象)产生关联;
则runtime方法前缀应该是objc(对象) ,_setAssociatedObject(关联另一个对象)
objc_getAssociatedObject(id object, const void *key)方法亦是如此;
网友评论