使用类别中的块扩展UIRefreshControl

时间:2013-10-15 13:58:23

标签: ios objective-c objective-c-blocks objective-c-category

我非常喜欢块的工作方式,并认为将它们添加到一些地方会很好,例如设置UIRefreshControl的操作。

所以我创建了categoryUIRefreshControl

@interface UIRefreshControl (Blocks)

@property (nonatomic, copy) void (^actionBlock)();

- (id)initWitActionBlock:(void (^)())actionBlock;

@end

@implementation UIRefreshControl (Blocks)

- (id)initWitActionBlock: (void (^)())actionBlock {
    self = [super init];
    if (self) {
        self.actionBlock = [actionBlock copy];
        [self addTarget:self action:@selector(fireActionBlock) forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

- (void)fireActionBlock {
        self.actionBlock();
}

@end

崩溃的原因:原因:' - [UIRefreshControl setActionBlock:]:无法识别的选择器发送到实例

但是我真的不知道块那么多,而且我并没有真正看到这个categorysubclass做同样事情的区别。

我想我不完全了解属性发生了什么,所以我的问题是我该怎么办?如果有可能,这可以吗?或者也许我不应该这样做?

编辑: *带有相关参考的解决方案感谢@Martin R!

static char const * const ActionBlockKey = "ActionBlockKey";

@interface UIRefreshControl (Blocks)

@property (nonatomic, copy) void (^actionBlock)();

- (id)initWitActionBlock:(void (^)())actionBlock;

@end

@implementation UIRefreshControl (Blocks)
@dynamic actionBlock;

- (id)initWitActionBlock: (void (^)())actionBlock {
    self = [super init];
    if (self) {
        self.actionBlock = [actionBlock copy];
        [self addTarget:self action:@selector(fireActionBlock) forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

- (void)fireActionBlock {
        self.actionBlock();
}

- (id)actionBlock{
    return objc_getAssociatedObject(self, ActionBlockKey);
}

- (void)setActionBlock:(void (^)())actionBlock{
    objc_setAssociatedObject(self, ActionBlockKey, actionBlock,  OBJC_ASSOCIATION_COPY_NONATOMIC);
}

@end

2 个答案:

答案 0 :(得分:1)

这个问题与街区无关。

编译器合成类类别中定义的属性, 因为这需要一个相应的实例变量,和 你无法在类别类别中添加实例变量

实际上你应该收到像

这样的警告
property 'actionBlock' requires method 'actionBlock' to be defined - use @dynamic or provide a method implementation in this category

我建议改为创建一个子类。

答案 1 :(得分:0)

我给你一些提示,但没有测试代码。请注意,您不应该像我刚才那样扩展UIKit类。

@interface MYUIRefreshControl:UIRefreshControl

@property (nonatomic, copy) void (^actionBlock)();

- (id)initWitActionBlock:(void (^)())actionBlock;

@end

@implementation MYUIRefreshControl
@synthesize actionBlock = _actionBlock;

- (id)initWitActionBlock: (void (^)())actionBlock {
    self = [super init];
    if (self) {
        _actionBlock = [actionBlock copy];
        [self addTarget:self action:@selector(fireActionBlock) forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

- (void)fireActionBlock {
      if(_actionBlock)
        _actionBlock();
}

@end