美文网首页iOS Dev
对象关联的使用objc_setAssociatedObject

对象关联的使用objc_setAssociatedObject

作者: 傻傻小萝卜 | 来源:发表于2016-07-06 16:32 被阅读2571次

    特性

    objective-c中,有类别可以在不修改源码的基础上增加方法;近排在看别人的开源代码时,发现还可以动态增加属性。而且是在运行时,太牛B了。

    使用运行时库,必须要先引入 objc/runtime.h

    可以使用的函数如下:

    OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

    创建关联要使用到Objective-C的运行时函数:objc_setAssociatedObject来把一个对象与另外一个对象进行关联。该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略。当然,此处的关键字和关联策略是需要进一步讨论的。

    关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。

    关联对象可以作为作为一个让源对象持有这个关键对象的方法(相当于将关键对象通过源对象传递),比如下面的label中的颜色,其中的objc_setAssociatedObject是将关联的对象传出,通过方法objc_getAssociatedObject(id object, const void *key) 获取到,例如下面的View中的block,是将block在objc_setAssociatedObject中定义,而在objc_getAssociatedObject得到block后实现。

    关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过使用预先定义好的常量来表示的。

    这个函数

    OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)

    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

    使用场景

    1.category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性

    属性 其实就是get/set 方法。我们可以使用  objc_setAssociatedObject/objc_getAssociatedObject  实现 动态向类中添加 方法

    UILabel+Associate.h

    #import <UIKit/UIKit.h>

    @interface UILabel (Associate)

    - (void) setFlashColor:(UIColor *) flashColor;

    - (UIColor *) getFlashColor;

    @end

    UILabel+Associate.m

    #import"UILabel+Associate.h"

    #import<object/runtime.h>

    @implementationUILabel (Associate)

    static char flashColorKey;

    - (void) setFlashColor:(UIColor *) flashColor{

    objc_setAssociatedObject(self,&flashColorKey, flashColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    - (UIColor *) getFlashColor{

    return objc_getAssociatedObject(self, &flashColorKey);

    }@end

    调用代码:

    UILabel *lab =[[UILabel alloc] init];

    [lab setFlashColor:[UIColor redColor]];

    NSLog(@"%@", [lab getFlashColor]);

    2.objc_setAssociatedObject与Block的简单使用

    UIAlertView的扩展

    .h文件

    #import <UIKit/UIKit.h>

    typedf void(^successBlock)(NSInteger buttonIndex);

    @interface UIAlertView(Block)

    - (void)showWithBlock:(successBlock)block;

    @end

    .m文件

    #import"UIAlertView+Block.h"

    #import

    static const char alertKey;

    @implementationUIAlertView(Block)

    - (void)showWithBlock:(successBlock)block{

    if(block)    {        

    objc_setAssociatedObject(self, &alertKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    self.delegate=self;    

    }   

     [self show];}

    - (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

    {    successBlock block = objc_getAssociatedObject(self, &alertKey);    

    block(buttonIndex);}

    @end

    UIButton的扩展

    .h文件

    #import

    typedef void(^btnBlock)();

    @interfaceUIButton(Block)

    - (void)handelWithBlock:(btnBlock)block;

    @end

    .m文件

    #import"UIButton+Block.h"

    #import <objc/runtime.h>

    static const char btnKey;

    @implementationUIButton(Block)

    - (void)handelWithBlock:(btnBlock)block{

    if(block)    {        

    objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);   

     }  

      [self addTarget:selfaction:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];

    }

    - (void)btnAction{   

    btnBlock block = objc_getAssociatedObject(self, &btnKey);    

    block();

    }

    @end

    这两个方法可以让一个对象和另一个对象关联,就是说一个对象可以保持对另一个对象的引用,并获取那个对象。有了这些,就能实现属性功能了。 policy可以设置为以下这些值:

    相关文章

      网友评论

        本文标题:对象关联的使用objc_setAssociatedObject

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