美文网首页
分享工作中Runtime关联对象的使用

分享工作中Runtime关联对象的使用

作者: 小苗晓雪 | 来源:发表于2019-01-08 11:01 被阅读3次

分享在分类中两个 objc_setAssociatedObject / objc_getAssociatedObject 关联对象方法的一点使用
ViewController.m文件

#import "ViewController.h"
#import <objc/runtime.h>
#import "UIButton+ActionButtonBlock.h"

#define ScreenWidth self.view.frame.size.width

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self setupUI];
}


- (void)setupUI
{
    // 第一个按钮:
    UIButton *button1 = [UIButton createBtnWithFrame:CGRectMake((ScreenWidth - 100) / 2, (ScreenWidth - 50) / 2 - 50, 100, 50) title:@"按钮A" ActionButtonBlock:^(UIButton *button) {
        
        float r = random()%255/255.0;
        float g = random()%255/255.0;
        float b = random()%255/255.0;
        self.view.backgroundColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0f];
        
    }];
    button1.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:button1];
    
    // 第二个按钮:
    UIButton *button2 = [UIButton createBtnWithFrame:CGRectMake((ScreenWidth - 100) / 2, CGRectGetMaxY(button1.frame) + 50, 100, 50) title:@"按钮B" ActionButtonBlock:nil];
    button2.actionButtonBlock = ^(UIButton *button) {
        
        NSLog(@"button.titleLabel.text = %@",button.titleLabel.text);
        
    };
    button2.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:button2];
    
    // 第三个按钮:
    UIButton *button3 = [UIButton createBtnWithFrame:CGRectMake((ScreenWidth - 100) / 2, CGRectGetMaxY(button2.frame) + 50, 100, 50) title:@"按钮C" ActionButtonBlock:nil];
    button3.buttonBlock = ^(UIButton *button) {
        
        NSLog(@"点击了按钮3");
        
    };
    button3.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:button3];
}

@end

UIButton+ActionButtonBlock.h文件

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

typedef void (^ActionButtonBlock)(UIButton *button);
typedef void (^ButtonBlock)(UIButton *button);

@interface UIButton (ActionButtonBlock)

@property(nonatomic, copy) ActionButtonBlock actionButtonBlock;
@property (nonatomic, copy) ButtonBlock buttonBlock;
+ (UIButton *)createBtnWithFrame:(CGRect)frame title:(NSString *)title ActionButtonBlock:(ActionButtonBlock)actionButtonBlock;

@end

UIButton+ActionButtonBlock.m文件

#import "UIButton+ActionButtonBlock.h"

static NSString *const kOfMethod;
static NSString *const kOfProperty;
static NSString *const kOfBlock;


@implementation UIButton (ActionButtonBlock)

+ (UIButton *)createBtnWithFrame:(CGRect)frame title:(NSString *)title ActionButtonBlock:(ActionButtonBlock)actionButtonBlock
{
    UIButton *button = [[UIButton alloc]init];
    button.frame = frame;
    [button setTitle:title forState:UIControlStateNormal];
    [button addTarget:button action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    
    // 1.这里两个block中的其中一个 , 它是你再初始化我这个button类的时候就带着的block , 他是通过方法key与button关联的block kOfMethod
    objc_setAssociatedObject(button, &kOfMethod, actionButtonBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    
    return button;
}

- (void)buttonClicked:(UIButton *)button
{
    // 获取两个个block
    ActionButtonBlock block1 = objc_getAssociatedObject(button, &kOfMethod);
    ActionButtonBlock block2 = objc_getAssociatedObject(button, &kOfProperty);
    if (block1)
    {
        block1(button);
    }
    else if (block2)
    {
        block2(button);
    }
    else if (self.buttonBlock)
    {
        self.buttonBlock(button);
    }
}

#pragma mark - 按钮 B 的 actionButtonBlock属性 的 Seter / Getter 方法
// 2.这是属性block的方法关联 , 他是通过属性的set / get方法与button相关联的 , 所以一会儿在viewController里你创建block 的时候如果block写nil , 再新的一行里通过button2.actionButtonBlock = ^(UIButton *button) { ... }; 这种属性的方法追加block那就是通过这种方法关联的block , 而不是初始化的那种block追加;
// 让 actionButtonBlock 作为UIButton的一个属性 , 让这个属性的set / get 方法与button自身关联
// 这里的关联写的是self , 这个self就是button啊 , 可别想成别的什么~
- (void)setActionButtonBlock:(ActionButtonBlock)actionButtonBlock
{
    objc_setAssociatedObject(self, &kOfProperty, actionButtonBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (ActionButtonBlock)actionButtonBlock
{
    return objc_getAssociatedObject(self, &kOfProperty);
}


#pragma mark - 按钮 C 的 buttonBlock 属性 的 Seter / Getter 方法
// 必须要关联对象才行 , 分类不能直接写set / get方法的实现
- (void)setButtonBlock:(ButtonBlock)buttonBlock
{
    objc_setAssociatedObject(self, &kOfBlock, buttonBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (ButtonBlock)buttonBlock
{
    return objc_getAssociatedObject(self, &kOfBlock);
}

@end

参考文章 : https://blog.csdn.net/u014220518/article/details/52873164
感谢作者的分享!

愿编程让这个世界更美好

相关文章

  • 分享工作中Runtime关联对象的使用

    分享在分类中两个 objc_setAssociatedObject / objc_getAssociatedObj...

  • NSRuntime使用篇

    使用总结runtime开源代码 对象的关联: 设置关联值 void objc_setAssociatedObjec...

  • 使用runtime关联对象

    一、添加属性 在使用类别时可以直接添加方法,不能直接添加属性,但是可以利用runtime中关联对象的方法添加属性。...

  • 为什么使用Runtime又可以添加属性?

    使用Runtime技术中的关联对象可以为类别添加属性。其原因是:关联对象都由AssociationsManager...

  • Runtime 关联对象的使用

    现在你准备用一个系统的类,但是系统的类并不能满足你的需求,你需要额外添加一个属性。 这种情况的一般解决办法就是继承...

  • Objective-C Runtime: 变量和属性

    本文只是整理Runtime中,成员变量、属性、关联对象、方法交换使用实例。不会很细致的讲解Runtime的内容,如...

  • iOS Runtime面试题(使用runtime Associa

    使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么? 无论在MRC下还是...

  • ios运行时一些方法说明

    一. 关联对象主要函数: 基本说明:关联对象就是runTime界的NSMultableDictionary voi...

  • Runtime - 关联对象

    马上就要开始新的项目,这个礼拜抽空来写一篇博客。于是就写一个比较贴近大家工作开发的runtime其中一个用法吧。一...

  • 关联对象底层结构

    关联对象的方法 runtime给我们提供了三个关于关联对象的方法,如下。点击查看如何添加关联对象[https://...

网友评论

      本文标题:分享工作中Runtime关联对象的使用

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