将块存储在数组中

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

编辑:没有进入太多的细节,在弧,你现在可以添加块像任何其他对象的集合 (见讨论)。

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


这引出了问题,阻止了第一类对象,还是仅仅为了在对象之间传递它们而将它们当作对象对待? 如果它们是第一类对象,那么它们不应该存储在数组中吗?

块是Objective-C对象,其行为与其他NSObject非常相似,但有一些关键的区别:

  • 块总是由编译器生成的。 当执行通过块声明时,它们在运行时被有效地“分配/初始化”。

  • 块最初是在堆栈上创build的。 如果块要超出当前范围,则必须使用 Block_copy()或copy方法将块移动到堆(请参见下面的ARC点)。

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

  • 要将一个块放入一个集合, 它必须先被复制总是。 包括在ARC下。 (请参阅注释)如果不这样做,存在分配的堆栈块将被autoreleased并且您的应用程序稍后会崩溃的风险。

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

  • 在ARC下,从一个方法或函数返回一个Block“just works”; 它会被自动复制到堆,返回将是一个自动释放的块(编译器可以在某些情况下优化autorelease)。 即使使用ARC,在将其粘贴到集合之前,仍然需要复制该块。

我写了几篇博客文章,提供了对块的介绍以及一些提示和技巧 。 你可能会觉得它们很有趣。

而且,是的,把它们添加到字典是非常有用的。 我已经写了一些代码,我把块放到字典中作为命令处理程序,其中键是命令名。 非常便利。

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

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

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