[iOS] 在category中使用block

在分类中使用属性block

通过分类我们可以为iOS UIKit 的常用控件添加方法,如果想添加属性怎么办呢,如果我们采用常规的方法定义属性,XCode会提示一下错误:
解决这个问题可以通过OC的runtime。
这里写图片描述

如果不写@dynamic block;
就会报上面的错误。
@dynamic 就是要告诉编译器,代码中用@dynamic修饰的属性,其getter和setter方法会在程序运行的时候或者用其他方式动态绑定,以便让编译器通过编译。这个跟@synthesize自动合成属性的getter/setter方法原理是不一样的。

#import <UIKit/UIKit.h>

typedef void(^doneBlock)();

@interface UIToolbar (STBar)

/** * 点击完成按钮的回调 */
@property (nonatomic,copy) doneBlock block;


/** * 创建带完成按钮的方法 */

- (void)createDoneButtonBar;

@end

对应的实现文件中对block属性通过objc_getAssociatedObject和objc_setAssociatedObject方法进行绑定。

#import "UIToolbar+STBar.h"
#import <objc/runtime.h>

static const void *UtilityKey = &UtilityKey;

@implementation UIToolbar (STBar)

@dynamic block;

- (doneBlock)block {
    return objc_getAssociatedObject(self, UtilityKey);
}

- (void)setBlock:(doneBlock)block{
    objc_setAssociatedObject(self, UtilityKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


- (void)createDoneButtonBar {
    UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(doneAction:)];

    UIBarButtonItem *space=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
    [space setWidth:250];

    [self setItems:@[space,done]];
}

- (void)doneAction:(UIButton *)button {
    if (self.block){
        self.block();
    }else{
        [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
    }
}

你可能感兴趣的:(ios,编译器)