4

我正在创建一个 barButton,按下它时应该将 UITableView 的编辑模式设置为是。这是我的代码:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @"Edit"
                                                                             style: self.navigationController.navigationItem.leftBarButtonItem.style
                                                                            target: self
                                                                             action: ];

我不明白的是我需要作为该action部分的参数放置什么,以便我可以在那里执行代码块。我可以很容易地提出@selector(someMethod),但我只执行一两行并且创建另一种方法是毫无意义的。

谢谢你的帮助!

4

2 回答 2

8

除了 pgb 的评论,写这样的东西可以解决问题:

@interface PJBlockHolder

+ (id)blockHolderWithBlock:(dispatch_block_t)block;
- (void)invoke;

@end

/* obvious implementation; copy the block, issue it upon invoke */

和:

[[UIBarButtonItem alloc] initWithTitle: @"Edit"
    style: self.navigationController.navigationItem.leftBarButtonItem.style
    target: [PJBlockHolderWithBlock:^{ /* your code here */ }]
    action:@selector(invoke) ];

因此,您创建了一个自定义对象,该对象包装了一个块并在特定选择器上发出它。

编辑:如下所述,UIControls 不保留其目标。所以可能最简单的事情是将块持有者的生命周期与控件的生命周期联系起来;这不一定是理想的,因为如果您随后将其作为目标删除,同时保持控件处于活动状态,那么持有者的寿命将超过其有用性,但它可能适用于大多数情况。

选项是使用 Objective-C 内置的关联对象,或者使用UIControl继承自的事实UIView,给它一个CALayer,它可以存储任意键对象。

Justin Spahr-Summers 在下面的评论中链接到前者的一个有据可查的公共领域实现,所以为了讨论的目的,我将展示后者的一个例子,即使它很hacky。

PJBlockHolderWithBlock *blockHolder = [PJBlockHolderWithBlock:^{ /* your code here */ }];
UIBarButtonItem *barButtonItem =
    [[UIBarButtonItem alloc] initWithTitle: @"Edit"
        style: self.navigationController.navigationItem.leftBarButtonItem.style
        target: blockHolder
        action:@selector(invoke) ];
[barButtonItem.layer setValue:blockHolder forKey:@"__myBlockHolderKey__"];
于 2012-07-03T20:22:31.190 回答
2

你不能按照你的意愿去做。这些target: action:参数旨在发送一个对象和一个要在该对象上调用的选择器。据我所知,没有使用块的等效 API。

于 2012-07-03T20:19:08.570 回答