繁体   English   中英

将Objective-C块声明为变量的最佳实践

[英]Best practice to declare Objective-C blocks as variable

我有一个关于将声明为变量的最佳实践的问题。

最初我写了我的块变量,如下所示:

id actionHandler = ^(UIAlertAction * action) {
    // Handling code
};

稍后使用如下:

UIAlertAction *action = [UIAlertAction actionWithTitle:@"Title"
                                                 style:UIAlertActionStyleDefault
                                               handler:actionHandler];

但是当我遇到Apple的Working With Blocks指南时,我看到我可以像这样重写它:

void (^actionHandler)(UIAlertAction * action) = ^(UIAlertAction * action) {
    // Handling code
};

这是宣告它的'正确'方式吗? 在我看来,这不是可读的,但我没有很多Objective-C的经验。 那么将块声明为变量的最佳实践是什么?


编辑:好的,谢谢大家的澄清! 定义一个typedef amin-negm-awad和其他人所示 ,似乎也是一个很好的替代方法。

这里没有一个通用的答案:当您将块变量声明为id您不再拥有与块关联的编译时信息,因此手动调用它会产生问题:

id myHandler = ^(NSString *str) {
    NSLog(@"%@", str);
};
// Error: Called object type id is not a function or function pointer
myHandler(@"Hello");

如果要从代码中直接调用块,则需要将其强制转换为块。

另一方面,如果仅声明块变量,以便可以将其传递给将块作为参数的函数,则使用id提供更易读的方法。

除了dasblinkenlicht提到的问题之外,我想问一个修辞问题:

可能你知道你可以替换这段代码......:

NSString *string = @"All about types";

...使用此代码:

id string = @"All about types";

你会怎么做? 我敢肯定,你没有。

那么为什么要将var的“类型”版本更改为id版本? 唯一的原因是,块类型的语法是不方便的,不易读取(并且不易编写)。 我总是定义一个具体的类型来摆脱不方便的语法:

typedef void (^ActionHandlerType)(UIAlertAction * action);

然后:

ActionHandlerType actionHandler = ^(UIAlertAction * action) {
  // Handling code
};

为了清楚起见:使用Objective-C的消息传递的动态特性, id非常棒。 但块执行既不是后期限制。 块的参数也不能改变其数量或类型,因此没有动态绑定。 这是一个简单的调用,固定数量的参数,固定类型。 因此, id的使用可能是块的对象性质的副作用。 但它不是用途,而是用途。

顺便说一句:如果在参数列表中使用具体类型,Xcode可以自动完成参数的语法。 有了id这是不可能的。 明显。

如果在此上下文中使用id ,则编译器不会检查您声明的块的类型是否与方法所期望的块的类型匹配。 如果你不小心弄错了块,很难调试,当方法试图使用块时可能会发生一些事情......

因此,如果你永远不会犯错误,请使用id ,但如果像我一样你提供正确的类型,那么编译器可以在你做的时候帮助你。

为了使其更容易,因此更不容易出错,请使用typedef,例如:

typedef void (^AlertActionHandler)(UIAlertAction * action);
...

AlertActionHandler actionHandler = ^(UIAlertAction * action) { ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM