zoukankan      html  css  js  c++  java
  • iOS objc_setAssociatedObject 关联对象的学习

    今天看了FDTemplateLayoutCell的源码,类别里面相当频繁使用了关联对象,做笔记!!!学套路

    主要函数:

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

    基本说明:关联对象就是runTime界的NSMultableDictionary 

    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)。
    使用场景:关联对象相当于实例变量,在类别(也有人管叫分类)里面,不能创建实例变量, 关联对象就可以解决这种问题。(对应属性,有对应属性的的runtime 解决方法,本篇文章主讲 关联对象学习)

    基本使用:举例创建 UIButton类别

    //
    //  UIButton+Block.h
    //  SectionDemo
    //
    //  Created by HF on 2017/7/13.
    //  Copyright © 2017年 HF-Liqun. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    typedef void (^btnBlock)(id sender);
    
    @interface UIButton (Block)
    
    - (void)handelWithBlock:(btnBlock)block;
    
    @end
    
    //
    //  UIButton+Block.m
    //  SectionDemo
    //
    //  Created by HF on 2017/7/13.
    //  Copyright © 2017年 HF-Liqun. All rights reserved.
    //
    
    #import "UIButton+Block.h"
    #import <objc/runtime.h>
    
    @implementation UIButton (Block)
    
    - (void)handelWithBlock:(btnBlock)block {
    
        if (block) {
            objc_setAssociatedObject(self,@selector(btnAction:) , block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        [self addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
    
    }
    
    - (void)btnAction:(id)sender
    {
        btnBlock block = objc_getAssociatedObject(self,@selector(btnAction:));
        if (block) {
            block(sender);
        }
    }
    
    @end

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

    自己设置静态变量做关键字:

    在FDTemplateLayoutCell 中 第二个参数进一步优化,出现了_cmd 代替了 &btnKey 或者 @selector(methodName).

    因为:
    _cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。

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

    这样处理好处是,该方法相对化简了繁文缛节,并且可读性良好。不容易写错key。

    参考 FDTemplateLayoutCell中使用_cmd 的使用

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

    (1)静态变量&btnKey  

    (2)@selector(methodName)

    (3)_cmd

    参考 

    (1)http://blog.csdn.net/luoyeffcs/article/details/27967193

    (2)http://blog.jobbole.com/79570/

    (3)http://www.jianshu.com/p/46cd19bc4b6b

    (4)http://www.jianshu.com/p/fdb1bc445266

     
  • 相关阅读:
    Smith Numbers POJ
    HDU
    dp HDU
    POJ
    HDU
    LOOPS HDU
    水题,P1789 【Mc生存】插火把 (暴力即可)
    LOOPS
    Coprime (单色三角形+莫比乌斯反演(数论容斥))
    莫比乌斯函数 51nod-1240(合数分解试除法)
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/7162613.html
Copyright © 2011-2022 走看看