8

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

typedef void (^BlockInBlock) (BlockInBlock block);

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


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

进一步的问题1:

如何实现一个可变参数函数,该函数需要我上面描述的许多块并以 结尾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 函数指针?

4

2 回答 2

11

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

typedef void (^Block)(id);

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

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

_block(_block);

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

所以,这就是想法。

于 2013-09-13T18:07:35.943 回答
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);
于 2013-09-13T17:40:38.810 回答