RunTime动态添加属性

一. 为什么要动态添加属性?

思考:当系统提供的类满足不了我们要求的时候, 则需我们手动添加属性,且希望能给系统直接添加属性;

以NSObject为例 (给NSObject 添加一个自定义属性)

  • 想法: 1. 创建一个子类继承NSObject, 此时可以添加属性;但是并不是直接给系统的类添加;
  • 想法: 2. 给NSObject添加一个分类, 在分类中我们可以实现方法, 但是添加属性, 仅仅只生成方法的声明;并没有方法实现和生成下划线成员变量;

二. 此时考虑使用runtime来动态实现给系统的类添加属性;

tips: 记得区分属性与成员变量

{
    NSString *_name; // 成员变量
}

@property (nonatomic, strong)NSString *name; // 成员属性

三. 实现步骤:

1.0 给NSObject 添加一个分类(Property),在里面添加一个自定义属性;

    #import 
    #import 

    @interface NSObject (Property)

    @property NSString *name; // 既然没有生成成员变量,那么无需策略进行修饰 

    @end

2.0 导入runtime的头文件,
3.0 在.h文件中实现name方法的getter 和setter方法

    #import "NSObject+Property.h"
    #import 

    @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)方法亦是如此;

你可能感兴趣的:(RunTime动态添加属性)