如何实现递归块?

时间:2013-09-13 17:07:14

标签: objective-c recursion block aop

我想声明一个块类型,它采用一个相同块类型的参数。就像这样:

typedef void (^BlockInBlock) (BlockInBlock block);

我知道声明无效。但我想知道是否有任何可能的方法来实现递归块,它只采用一个相同块类型的参数。


我正在尝试使用块在Objective-C中实现面向方面编程(AOP)的方法。以下是关于如何实现这一点的问题。

进一步问题1:

如何实现一个variadic function,它占用了我上面描述的许多块,并以nil结束,我可以用多个块调用该函数,直到遇到nil?它会是这样的:

@interface NSObject(AOP)
- (void) invokeBlockInBlock:(BlockInBlock) headBlock, ...{
    va_list blockList;
    va_start(blockList, headBlock);

    // Invoke recursive blocks here until the value of va_arg(blockList, BlockInBlock) is nil
    // it would be like: block1(self, block2(self, block3(self, block4(...))));

    va_end(blockList);
}
@end

进一步问题2:

如果递归块有返回值怎么办?


关于C语言的其他问题:

是否可以声明一个C函数,它接受一个C函数指针的参数,而C函数指针的函数也需要另一个C函数指针?

2 个答案:

答案 0 :(得分:11)

可能与您正在寻找的相似:

typedef void (^Block)(id);

从字面上看,它将导致无限递归循环:

Block _block;
_block = ^(Block block) {
    if (block) block(block);
};

_block(_block);

然而,参数可以是任何id,不仅是完全相同的Block,而且它表示如何将同一个块作为参数传递给同一个块。

所以,这个想法。

答案 1 :(得分:4)

通过捕获__block引用中的块来实现此操作要容易得多。实际上,根本不支持C中泛型类型的前向声明。那么,这可能是唯一的解决方案吗?

__block void(^strawberryFields)();
strawberryFields = ^{ strawberryFields(); };
strawberryFields();

请注意,如果您计划异步调度该块,则必须在分配之前复制它(在ARC下不再需要 ):

__block void(^strawberryFields)();
strawberryFields = [^{ strawberryFields(); } copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
               strawberryFields);