执行代码块代替@selector [英] Executing Code Block In Place Of @selector

查看:124
本文介绍了执行代码块代替@selector的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating a barButton which when pressed should set the editing mode of a UITableView to yes. Here's my code:

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

我不理解的是我需要将其作为action部分的参数,以便在那里执行代码块.我可以很容易地放@selector(someMethod),但是我只执行一两行,而创建另一种方法却毫无意义.

What I don't understand is what I need to put as an argument for the action part so that I can execute a code block there. I could easily enough put @selector(someMethod) but I'm only executing one or two lines and creating another method is pretty pointless.

感谢您的帮助!

推荐答案

进一步pgb的注释,编写这样的内容可以解决问题:

Further to pgb's comment, writing something like this would solve the problem:

@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) ];

因此,您已经创建了一个自定义对象,该对象包装了一个块并将其发布到特定的选择器上.

So you've created a custom object that wraps a block and issues it upon a particular selector.

如下所述,UIControl不保留其目标.因此,最简单的方法可能是将块保持器的寿命与控件的寿命联系起来.这不一定是理想的,因为如果您随后在保持控件有效的情况下随后将其作为目标删除,那么持有人将无法发挥其作用,但是它可能适用于大多数情况.

as noted below, UIControls don't retain their targets. So probably the easiest thing is to tie the lifetime of the block holder to the lifetime of the control; that's not necessarily ideal because then the holder will outlive its usefulness if you subsequently remove it as a target while keeping the control alive, but it's probably suitable for the majority of cases.

选项要么是使用Objective-C的内置关联对象,要么是使用UIControl继承自UIView的事实,从而赋予它CALayer,它可以存储任意键对象.

Options are either to use Objective-C's built in associated objects, or to use the fact that UIControl inherits from UIView, giving it a CALayer, which can store arbitrary keyed objects.

Justin Spahr-Summers在下面的评论中链接到前者的一个有据可查的,公共领域的实现,因此出于讨论的目的,我将展示后者的一个示例,即使它很笨拙.

Justin Spahr-Summers links to a well documented, public domain implementation of the former in his comment below so I'll show an example of the latter, even though it's hacky, for the purposes of discussion.

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__"];

这篇关于执行代码块代替@selector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆