块数组?

时间:2012-07-26 19:42:22

标签: objective-c nsarray objective-c-blocks

这对我来说似乎是一种非常奇怪的互动,但同时它不仅起作用,而且在此过程中不会引发任何警告或错误。只是希望更好地理解一般的块,以及为什么这样的事情是对还是错。

有什么理由不应该这样做吗?

NSArray *array = [NSArray arrayWithObjects:^{NSLog(@"Block 1");}, ^{NSLog(@"Block 2");}, ^{NSLog(@"Block 3");}, nil];

for (id block in array) {
    [block invoke];
}

3 个答案:

答案 0 :(得分:4)

将块放入NSArray s很好;他们是对象。事实上,他们继承自NSObject

但是,您确实需要复制它们。这些块是在堆栈上创建的,需要移动到堆中才能超过当前方法的结尾。如果您正在使用ARC,这很容易:

NSArray *array = [NSArray arrayWithObjects:[^{NSLog(@"Block 1");} copy], ...

在MRR下,您需要平衡copy,因此您有两个不愉快的选项:使用temps,或在创建数组后立即枚举数组并将release发送给其所有成员。

另一方面,发送invoke并非完全犹太教,因为这是私有方法。调用块的唯一完全API兼容的方法是使用函数调用语法:

typedef GenericBlock dispatch_block_t;
for( GenericBlock block in array ){
    block();
}

答案 1 :(得分:1)

当然,那没关系。为什么不好?

在像JavaScript这样的语言中,这种技术在注册事件处理程序时很常见。

object.clickHandlers.push(function() { doStuff() });
object.clickHandlers.push(function() { doMoreStuff() });

我认为类似的技术不能与ObjC块一起使用,因为它们是真实的对象。

对我来说,更有趣的问题是,无论你的目标是什么,这种模式是最好的选择。你没有真正告诉过我们。

答案 2 :(得分:1)

Objective-C中的块是“一等公民”对象。无论你对常规对象做什么,无论是作为参数传递,存储在数组还是字典中,依此类推,你都可以阻止对象。

例如,块对象数组可用于编码在编译时未知的一系列动作;字符串键控的块对象字典可用于实现脚本语言,等等。

调用从集合中检索的块的最佳方法是将其转换为正确的类型,并使用常规块调用语法。