美文网首页
iOS objc_setAssociatedObject 关联对

iOS objc_setAssociatedObject 关联对

作者: 路有点颠簸 | 来源:发表于2019-01-08 14:27 被阅读11次

    主要函数

    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);
    

    相关说明

    objc_setAssociatedObject 相当于 setValue:forKey 进行关联value对象
    
    objc_getAssociatedObject 用来读取对象
    
    objc_AssociationPolicy  属性 是设定该value在object内的属性,即 assgin, (retain,nonatomic)...等
    
     objc_removeAssociatedObjects 函数来移除一个关联对象,或者使用objc_setAssociatedObject函数将key指定的关联对象设置为nil。
    

    相关参数

    key:要保证全局唯一,key与关联的对象是一一对应关系。必须全局唯一。通常用@selector(methodName)作为key。
    value:要关联的对象。
    policy:关联策略。有五种关联策略。
    OBJC_ASSOCIATION_ASSIGN 等价于 @property(assign)。
    OBJC_ASSOCIATION_RETAIN_NONATOMIC等价于 @property(strong, nonatomic)。
    OBJC_ASSOCIATION_COPY_NONATOMIC等价于@property(copy, nonatomic)。
    OBJC_ASSOCIATION_RETAIN等价于@property(strong,atomic)。
    OBJC_ASSOCIATION_COPY等价于@property(copy, atomic)。
    

    应用场景

    关联对象相当于实例变量,在类别(也有人管叫分类)里面,不能创建实例变量, 关联对象就可以解决这种问题。

    使用举例

    typedef void(^btnBlock)(id sender);
    @interface UIButton (Block)
    
    - (void)handleWithBlock:(btnBlock)block;
    @end
    
    #import "UIButton+Block.h"
    #import <objc/runtime.h>
    
    static NSString *btnKey = @"safsaf";
    @implementation UIButton (Block)
    
    - (void)handleWithBlock:(btnBlock)block{
        if (block) {
            objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        [self addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    - (void)btnAction:(id)send{
        btnBlock block = objc_getAssociatedObject(self, &btnKey);
        if (block) {
            block(send);
        }
    }
    
    @end
    

    是第二个参数 const void *key 类型通常都是通常都是会采用静态变量来作为关键字 可以自己创建 也可以使用"@selector(btnAction:) "。

    扩展

    可对第二个参数进一步优化,用_cmd 代替了 &btnKey 或者 @selector(methodName).
    _cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。

    强调

    _cmd的作用域只在当前方法里,直指当前方法名@selector。例如:

    - (void)btnAction:(id)send{
        btnBlock block = objc_getAssociatedObject(self, _cmd);
        //这里_cmd相当于@selector(btnAction:)
        if (block) {
            block(send);
        }
    }
    
    WX20190108-115018.png

    至此,设置关联对象关键key,一共有三种写法:

    (1)静态变量&btnKey

    (2)@selector(methodName)

    (3)_cmd

    相关文章

      网友评论

          本文标题:iOS objc_setAssociatedObject 关联对

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