RunTime动态添加属性

作者: 其字德安 | 来源:发表于2016-03-27 01:05 被阅读1218次

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

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

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

    相关文章

      网友评论

      本文标题:RunTime动态添加属性

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