在数组中存储块

时间:2011-11-03 15:38:44

标签: objective-c memory-management objective-c-blocks

在Objective-C中,我知道块被认为是对象,所以我想知道是否可以将它们存储在数组中。这引出了一个问题,是阻止第一类对象还是只是为了在对象之间传递它们而被视为对象?如果它们是第一类对象,那么它们不应该存储在数组中吗?

2 个答案:

答案 0 :(得分:90)

  

编辑:在ARC下,没有太多细节,您现在可以像其他任何对象一样向集合添加块(参见讨论)。

我在下面保留原始答案,因为它包含一些有趣的技术细节。


  

这引出了一个问题,是阻止第一类对象还是它们   为了在两者之间传递而对待对象   对象?如果他们是头等对象,那么他们不应该是   在阵列中存储?

块是Objective-C对象,其行为与其他NSObject类似,但有几个主要区别:

  • 块总是由编译器生成。当执行通过块声明时,它们在运行时实际上是“alloc / init”。

  • 最初在堆栈上创建块。如果Block要比当前范围更长,则必须使用Block_copy()或copy方法移动到堆中(参见下面的ARC点)。

  • 除了内存管理之外,块实际上没有可调用的API。

  • 要将块放入集合,必须先复制。 <击>始终。包括在ARC下。 (请参阅注释。)如果不这样做,则存在堆栈分配阻止为autoreleased并且您的应用稍后会崩溃的风险。

  • 复制基于堆栈的块也将复制所有捕获的状态。如果你要制作一个块的多个副本,复制它一次更有效,然后复制副本(因为复制副本只会碰到保留计数,因为块是不可变的)。

  • 在ARC下,从方法或函数返回一个块“只是工作”;它将被自动复制到堆中,并且返回将实际上是一个自动释放的块(编译器可以在某些情况下优化自动释放)。即使使用ARC,您仍然需要先复制块,然后再将其粘贴到集合中。

我写了几篇博文,其中提供了introduction to blocks和一些tips and tricks。你可能会发现它们很有趣。

而且,是的,将'em添加到词典中非常有用。我已经编写了几个代码,我把块作为命令处理程序放到字典中,其中键是命令名。非常方便。

答案 1 :(得分:39)

是的,块确实是对象,您可以将它们放在数组中:

NSMutableArray *arr = [NSMutableArray new];
[arr addObject:^(){NSLog(@"my block");}];
void (^ myblock)() = [arr objectAtIndex:0];
myblock();

这会将“我的块”放在控制台中。