美文网首页
Runtime应用系列:关联对象

Runtime应用系列:关联对象

作者: 羊非鱼丶 | 来源:发表于2018-07-26 15:31 被阅读0次

    AssociatedObject

    对象实例化后不能动态添加属性,除非在动态创建一个类时。如果想给一个已经存在的对象添加属性,就需要通过关联对象(Associated Object)实现这个需求。关联对象相当于把一个对象关联到另外一个对象上。在关联后可以随时获取该关联的对象,在对象销毁时会移除所有关联的对象。而在Category当中,正常情况下为其添加属性会报错,因为它不会自动生成settergetter,所以就需要使用关联对象来为其实现添加的属性。

    • 为实例化后的对象动态添加属性
    #import "ViewController.h"
    #import "MyClass.h"
    #import <objc/runtime.h>
    @interface ViewController ()
    
    @end
    
    static const void *kAssociatedKey = &kAssociatedKey;
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        MyClass *myClass = [[MyClass alloc] init];
        
        objc_setAssociatedObject(myClass, kAssociatedKey, @"associatedObject", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        
        NSString *assciatedString2 = objc_getAssociatedObject(myClass, kAssociatedKey);
        NSLog(@"关联后的结果:%@",assciatedString2);
    }
    

    打印出的结果:


    Xnip2018-07-26_15-15-53
    • Category添加属性

    .h文件:

    @interface UIViewController (MyVC)
    @property (nonatomic, strong) NSString *associatedString;
    
    @end
    

    .m文件

    #import "UIViewController+MyVC.h"
    #import <objc/runtime.h>
    
    static const void *kAssociatedKey = &kAssociatedKey;
    
    @implementation UIViewController (MyVC)
    -(void)setAssociatedString:(NSString *)associatedString {
        objc_setAssociatedObject(self, kAssociatedKey, associatedString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSString *)associatedString {
        return objc_getAssociatedObject(self, kAssociatedKey);
    }
    
    @end
    
    

    调用及结果:

    #import "ViewController.h"
    #import "UIViewController+MyVC.h"
    @interface ViewController ()
    @end
    
    static const void *kAssociatedKey = &kAssociatedKey;
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.associatedString = @"category";
        NSLog(@"%@", self.associatedString);    
    }
    
    
    Xnip2018-07-26_15-19-27

    大道同宗,通过objc_setAssociatedObject给对象关联一个字符串(属性),再通过objc_getAssociatedObject获取关联的值。其中objc_setAssociatedObject的四个参数分别为原关联对象、关联属性key、关联属性和关联策略,第二个参数key要保持唯一性,一般写法有以下三种:

    • 声明static void *kAssociatedKey,将&kAssociatedKey作为key
    • 声明static const void *kAssociatedKey = &kAssociatedKey,将&kAssociatedKey作为key
    • selector作为key

    最后一个参数objc_AssociationPolicy用于指定关联的策略,用法参考官方文档中的说明。

    typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
        OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
        OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                                *   The association is not made atomically. */
        OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                                *   The association is not made atomically. */
        OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                                *   The association is made atomically. */
        OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                                *   The association is made atomically. */
    };
    
    

    相关文章

      网友评论

          本文标题:Runtime应用系列:关联对象

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