哪个是正确的,nil或NULL,标记"没有Objective-C块"?

Eon*_*nil 63 syntax objective-c objective-c-blocks

如果我想为Objective-C块传递任何内容,我应该使用什么关键字,NULL或者nil?我问这个是因为Objective-C块是Objective-C对象(据我所知),但表示为函数指针.

NULL并且nil两者都表示0x0指针,但它们在语义上是不同的.所以我很担心这个.

zne*_*eak 83

块不表示为函数指针.它们被表示为块,这^在它们的声明中用符号表示.在幕后,唯一的相似之处是调用语法.否则,他们都非常非常不同.

调用它们的方法通常很有用.例如,如果您不使用垃圾收集,则需要copy在块上调用该方法,以便以后保留它们.随着自动保留计数的出现,这甚至是复制块的唯一方法,因为ARC指针强制转换规则阻止您使用Block_copy宏.

NULL是,取决于你的编译器,只是0(void*)0.这适用于任何类型的指针.但是,由于Objective-C的语言规则,如果您尝试将消息发送到无法直接转换为的类型id(如果使用ARC则出现错误),则会收到警告.

由于将消息发送到块可能很有用,因此您应该使用nil它们.


[编辑]让我们清楚,使用nilNULL将导致完全相同的二进制代码.您对常量的选择应该基于您是否将块视为Objective-C对象.在您必须编写自己的电话retainrelease电话时,这是一个更大的交易,但现在ARC为您完成所有内存管理工作.

如果你在ARC之前使用了块,你可能会认为它们是Objective-C对象.如果没有,那么你可能不会想到/意识到它们是.在语言中仍然有一些他们身份的遗物(例如,你可以有一个__weak__unsafe_unretained指向一个块的指针),但在大多数情况下,差异可以忽略不计.选择一个并尝试坚持下去.我喜欢将我的块视为Objective-C对象.

  • +1,例如动画的UIView类方法可以有一个参数`completion`,暗示为`(void(^)(BOOL finished))completion`,文档说:可能是NULL.所以我不确定传递nil是否是预期的用途.请详细说明一下. (13认同)
  • @Nick Weaver你也可以对任何Objective-C类型使用`NULL`.'nil`首选的唯一原因是它满足编译器,因为`nil`是`id`类型,并且它向`id`发送消息是有效的,而它不是向void指针发送消息(它会发出警告).由于块是对象,因此没有充分的理由不对它们使用`nil`. (13认同)