是否可以为 UIButton
中的 @selector
参数传递一个 Objective-C block ?即,有没有办法让以下工作?
[closeOverlayButton addTarget:self
action:^ {[anotherIvarLocalToThisMethod removeFromSuperview];}
forControlEvents:UIControlEventTouchUpInside];
谢谢
最佳答案
是的,但您必须使用类别。
类似:
@interface UIControl (DDBlockActions)
- (void) addEventHandler:(void(^)(void))handler
forControlEvents:(UIControlEvents)controlEvents;
@end
实现会有点棘手:
#import <objc/runtime.h>
@interface DDBlockActionWrapper : NSObject
@property (nonatomic, copy) void (^blockAction)(void);
- (void) invokeBlock:(id)sender;
@end
@implementation DDBlockActionWrapper
@synthesize blockAction;
- (void) dealloc {
[self setBlockAction:nil];
[super dealloc];
}
- (void) invokeBlock:(id)sender {
[self blockAction]();
}
@end
@implementation UIControl (DDBlockActions)
static const char * UIControlDDBlockActions = "unique";
- (void) addEventHandler:(void(^)(void))handler
forControlEvents:(UIControlEvents)controlEvents {
NSMutableArray * blockActions =
objc_getAssociatedObject(self, &UIControlDDBlockActions);
if (blockActions == nil) {
blockActions = [NSMutableArray array];
objc_setAssociatedObject(self, &UIControlDDBlockActions,
blockActions, OBJC_ASSOCIATION_RETAIN);
}
DDBlockActionWrapper * target = [[DDBlockActionWrapper alloc] init];
[target setBlockAction:handler];
[blockActions addObject:target];
[self addTarget:target action:@selector(invokeBlock:) forControlEvents:controlEvents];
[target release];
}
@end
一些解释:
- 我们正在使用一个名为
DDBlockActionWrapper
的自定义“仅限内部”类。这是一个简单的类,它有一个 block 属性(我们想要调用的 block )和一个简单地调用该 block 的方法。 UIControl
类别只是简单地实例化这些包装器之一,为其提供要调用的 block ,然后告诉自己使用该包装器及其invokeBlock:
方法作为目标和行动(正常)。UIControl
类别使用关联对象来存储DDBlockActionWrappers
数组,因为UIControl
不保留其目标。该数组是为了确保 block 在应该被调用时存在。我们必须确保实际上,associated objects are cleaned up automatically during deallocation .DDBlockActionWrappers
在对象被销毁时得到清理,所以我们正在做一个令人讨厌的 hack 调出-[UIControl dealloc]
使用一个新的删除关联对象,然后调用原始dealloc
代码。棘手,棘手。
最后,这段代码是在浏览器中输入的,并没有被编译。它可能有一些问题。您的里程可能会有所不同。
关于objective-c - 我可以使用 Objective-C 将 block 作为 @selector 传递吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4581782/