在Objective-C中使用递归匿名块

时间:2013-03-23 18:58:00

标签: objective-c objective-c-blocks

我喜欢JavaScript将函数定义为变量的能力,并尝试在Objective-C中执行类似的操作。特别是,我想使用一个匿名块来编写一个递归函数,我可以在一个对象上调用它并让它在树中运行,在每个节点上应用一个更改:

void ( ^setDetailsLoaded )( Product* ) = ^void ( Product* prod ) {
    prod.detailsLoaded = true;
    for ( Group* group in prod.groups ) {
        for ( Product* mod in group.mods )
            setDetailsLoaded( mod );
    }
};
setDetailsLoaded( product ); <-- error here

然而,当我运行程序(编译正常)时,我得到了奇怪的错误error: address doesn't contain a section that points to a section in a object file [sic]。

我只是想知道是否需要保留块或其他内容,或者我是否应该使用函数指针而不是块来执行此操作。

1 个答案:

答案 0 :(得分:3)

由于块的实现方式 - 它们构成了所有原始类型变量的const副本,并且在创建时对它们中引用的所有对象类型变量的强引用 - 尝试以递归方式引用其自身内的块将导致你看到的崩溃。

您可以通过在块变量本身上使用__block注释来解决此问题:

__block void ( ^setDetailsLoaded )( Product* ) = ^void ( Product* prod ) {
    prod.detailsLoaded = true;
    for ( Group* group in prod.groups ) {
        for ( Product* mod in group.mods )
            setDetailsLoaded( mod );
    }
};

有关详细信息,请参阅@bbum's blog post on blocks(特别是提示#7)。