我非常喜欢块的工作方式,并认为将它们添加到一些地方会很好,例如设置UIRefreshControl
的操作。
所以我创建了category
到UIRefreshControl
@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:]:无法识别的选择器发送到实例
但是我真的不知道块那么多,而且我并没有真正看到这个category
和subclass
做同样事情的区别。
我想我不完全了解属性发生了什么,所以我的问题是我该怎么办?如果有可能,这可以吗?或者也许我不应该这样做?
编辑: *带有相关参考的解决方案感谢@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
答案 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