美文网首页
Runtime 之关联对象

Runtime 之关联对象

作者: 有梦想的狼 | 来源:发表于2020-03-05 10:19 被阅读0次

    关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上。

    关联对象的原理:

    关联对象的原理

    Runtime提供的API:

    //关联对象
    void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    //获取关联的对象
    id objc_getAssociatedObject(id object, const void *key)
    //移除关联的对象
    void objc_removeAssociatedObjects(id object)
    

    参数说明:

    id object:被关联的对象。
    const void *key:关联的key,要求唯一。在比较两个关联对象是否相等时,比较的就是内存地址,所以一般用一个全局静态变量表示
    id value:关联的对象。
    objc_AssociationPolicy policy:内存管理的策略。
    

    objc_AssociationPolicy policy的enum值有:

    typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
        OBJC_ASSOCIATION_ASSIGN = 0,           //指定一个弱引用关联的对象,等效于assign
        OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //指定一个非原子性的强引用关联的对象,等效于nonatomic,retain
        OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   //指定一个非原子性的copy关联的对象,等效于nonatomic,copy
        OBJC_ASSOCIATION_RETAIN = 01401,       //指定一个原子性的强引用关联的对象,等效于atomic,retain
        OBJC_ASSOCIATION_COPY = 01403          //指定一个原子性的copy关联的对象,等效于atomic,copy
    };
    

    当对象被释放时,会根据这个策略来决定是否释放关联的对象,当策略是RETAIN/COPY时,会释放(release)关联的对象,当是ASSIGN,将不会释放。
    值得注意的是,我们不需要主动调用removeAssociated来接触关联的对象,如果需要解除指定的对象,可以使用setAssociatedObject设置为nil来实现。

    关联对象的使用:

    给NSArray添加属性,只能使用category。

    • 创建NSArray的category,NSArray+Category.h文件:
    #import <Foundation/Foundation.h>
    
    @interface NSArray (Category)
    
    //不会生成添加属性的getter和setter方法,必须我们手动生成
    @property (nonatomic, copy) NSString *blog;
    
    @end
    
    • NSArray+Category.m文件:
    #import "NSArray+Category.h"
    #import <objc/runtime.h>
    
    @implementation NSArray (Category)
    
    /**
     blog的getter方法
     */
    - (NSString *)blog
    {
        // 根据关联的key,获取关联的值。
        return objc_getAssociatedObject(self, @selector(blog));
    }
    
    /**
     blog的setter方法
     */
    - (void)setBlog:(NSString *)blog
    {
        // 第一个参数:给哪个对象添加关联
        // 第二个参数:关联的key,通过这个key获取
        // 第三个参数:关联的value
        // 第四个参数;关联的策略
        objc_setAssociatedObject(self, @selector(blog), blog, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end
    
    • 测试代码:
    NSArray *myArray = [[NSArray alloc]init];
    myArray.blog = @"http://www.imlifengfeng.com";
    NSLog(@"blog=%@",myArray.blog);
    

    打印结果:

    2016-12-25 20:00:37.824 RunTimeTest[9447:958867] blog=http://www.imlifengfeng.com
    

    相关文章

      网友评论

          本文标题:Runtime 之关联对象

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