objective-c - 我可以使用 Objective-C 将 block 作为 @selector 传递吗?

标签 objective-c cocoa-touch

是否可以为 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

一些解释:

  1. 我们正在使用一个名为 DDBlockActionWrapper 的自定义“仅限内部”类。这是一个简单的类,它有一个 block 属性(我们想要调用的 block )和一个简单地调用该 block 的方法。
  2. UIControl 类别只是简单地实例化这些包装器之一,为其提供要调用的 block ,然后告诉自己使用该包装器及其 invokeBlock: 方法作为目标和行动(正常)。
  3. UIControl 类别使用关联对象来存储 DDBlockActionWrappers 数组,因为 UIControl 不保留其目标。该数组是为了确保 block 在应该被调用时存在。
  4. 我们必须确保 DDBlockActionWrappers 在对象被销毁时得到清理,所以我们正在做一个令人讨厌的 hack 调出 -[UIControl dealloc] 使用一个新的删除关联对象,然后调用原始 dealloc 代码。棘手,棘手。 实际上,associated objects are cleaned up automatically during deallocation .

最后,这段代码是在浏览器中输入的,并没有被编译。它可能有一些问题。您的里程可能会有所不同。

关于objective-c - 我可以使用 Objective-C 将 block 作为 @selector 传递吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4581782/

相关文章:

iphone - MBProgressHud 不随设备方向改变。?

iphone - 如何以编程方式缩放 UIScrollView?

ios - 单击按钮时隐藏键盘?

ios - 如何曲线 CGMutablePath?

ios - 如何将带有负整数的 NSString 转换为负整数

ios - Obj-c - 将 NSDictionary 添加到 NSMutableArray?

ios - createPreparedCellForItemAtIndexPath 中的 UICollectionView 断言失败

ios - UITableViewCell 重新排序 : cell stops moving 10 pixels into the drag

ios - 仅视网膜设备的图像名称?

objective-c - 为什么我的核心数据模型不再起作用? Integer16 值翻转?