美文网首页iOS 细碎Objective-Cselector
objc_setAssociatedObject与Block的简

objc_setAssociatedObject与Block的简

作者: Lonely__M | 来源:发表于2015-07-20 18:53 被阅读11979次
    • UIAlertView的扩展

    .h文件

    #import <UIKit/UIKit.h>
    typedef void (^successBlock)(NSInteger buttonIndex);
    
    @interface UIAlertView (Block)<UIAlertViewDelegate>
    
    - (void)showWithBlock:(successBlock)block;
    
    @end
    

    .m文件

    
    #import "UIAlertView+Block.h"
    #import <objc/runtime.h>
    
    static const char alertKey;
    
    @implementation UIAlertView (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 <UIKit/UIKit.h>
    
    typedef void (^btnBlock)();
    
    @interface UIButton (Block)
    
    - (void)handelWithBlock:(btnBlock)block;
    
    @end
    

    .m文件

    
    #import "UIButton+Block.h"
    #import <objc/runtime.h>
    
    static const char btnKey;
    
    @implementation UIButton (Block)
    
    - (void)handelWithBlock:(btnBlock)block
    {
        if (block)
        {
            objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        
        [self addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
    }
    
    - (void)btnAction
    {
        btnBlock block = objc_getAssociatedObject(self, &btnKey);
        block();
    }
    
    @end
    

    tips: 使用objc_setAssociatedObject,需要引入头文件 #import <objc/runtime.h>


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

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

    enum {OBJC_ASSOCIATION_ASSIGN = 0,
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
    OBJC_ASSOCIATION_RETAIN = 01
    OBJC_ASSOCIATION_COPY = 01403
    };
    

    相关文章

      网友评论

      • 午马丶:我想问下 ,这个关联的这个东西 为什么我总感觉就是装X用的呢 , 他的那种用法 完全可以不用那样的啊 ,也没有简便多少。 能给说说它的特殊的地方和真正的用途吗? 谢谢
      • 我觉得ok_:楼主有demo可以提供吗?没看懂如何使用
      • 翻滚的炒勺2013:不知道怎么用~!
      • LD_左岸:如果在类别中 对类别里的属性的set 和 get方法用Runtime的以上两个方法是什么意思呢
        比如
        #import <UIKit/UIKit.h>
        @class CustomView;
        @interface UICollectionView (Custom)
        @property(nonatomic,weak)CustomView *view;





        #pragma mark-关联头部
        -(void)setHeader:(CustomView *)header
        {
        objc_setAssociatedObject(self, @selector(header), header, OBJC_ASSOCIATION_ASSIGN);
        }

        - (CustomView *)header
        {
        return objc_getAssociatedObject(self, @selector(header));
        }
        小胡昵称已被占用:分类category也就是你说的类别中的property,编译器不会帮你自动生成set/get方法,你必须自己实现get/set方法,否则调用这个property会报错。在实现get/set方法的时候,你只能用这种assosiated的方式来存储自己的数据。
      • LD_左岸:小弟问个浅显的问题 在项目中大量的使用Runtime的东西 对审核是没影响的是吗
        Lonely__M:@左岸__ 基本没有影响,但是涉及到私有API苹果审核还是影响的
      • 念奴娇如画:报错啊,为什么
      • 巴糖:能完善下讲解吗
      • 娘亲Joanna:没看一点懂啊,
      • 6e331ee478cb:Hi,想问你下,
        #import <objc/objc-runtime.h>
        里面包含了
        #include <objc/runtime.h>
        #include <objc/message.h>
        和单独的用 #include <objc/runtime.h>有区别吗?我看有的人用前者啊!?
        moxuyou:import能防止重复导入,还是有区别的
        wind_dy:@jialinlv 没有区别,<objc/objc-runtime.h>只是把<objc/runtime.h>和<objc/message.h>放在一个头文件里面,导入前者就相当于不后两者导入了
      • 囧囧侠:你好,为什么用OBJC_ASSOCIATION_RETAIN_NONATOMIC,而不用OBJC_ASSOCIATION_COPY_NONATOMIC呢?毕竟block是用copy来修饰的
        小胡昵称已被占用:对block来说retain和copy是一样的
        囧囧侠:@Lonely__ 但是网上更多的例子还是用的OBJC_ASSOCIATION_RETAIN_NONATOMIC :scream:
        Lonely__M:@囧囧侠 我的错,应该用copy的,谢谢指正😄
      • 4305824b6977:学习了,感谢
      • FengxinLi:@Je_amo 就是直接在block里面处理点击事件。恩明白了 。谢谢
      • Lonely__M:@Fengxinliju block是用来回调方法,动态的给button添加一个回调block,这样就可以直接执行按钮点击事件
        翻滚的炒勺2013:@佛克斯 明白了
        佛克斯:@Lonely__ 可以这样理解吧,一些UI控件(不仅仅是文中的两个控件),只要这些控件当有触发事件时,会调用另外的执行方法或是代理方法,都可以通过本文中介绍的方法,利用block方式来实现相应的执行方法或是代理方 法。这样就可以利用起来block的优点了,比如block可以直接捕获上下文中的量。 :blush:
      • FengxinLi:@Je_amo UIButton增加的个类别,我没看明白,你这个block的作用是什么呢?这样子有什么好处?可以加QQ吗?我的QQ:1203420007
      • Lonely__M:@Fengxinliju 你好,button是和传入的block关联,然后在点击事件里,用block回调
      • FengxinLi:请问一下 你button是和那个对象关联的?

      本文标题:objc_setAssociatedObject与Block的简

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