在Objective-C中,我知道块被认为是对象,所以我想知道是否可以将它们存储在数组中。这引出了一个问题,是阻止第一类对象还是只是为了在对象之间传递它们而被视为对象?如果它们是第一类对象,那么它们不应该存储在数组中吗?
答案 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();
这会将“我的块”放在控制台中。