How to implement recursive blocks?

I want to declare a block type that takes one parameter, which is the same block type. This is something like this:

typedef void (^BlockInBlock) (BlockInBlock block); 

I know the ad is not valid. But I am wondering if there is any possible way to implement a recursive block that takes only one parameter, which is the same type of block.


I am trying to find a way to implement aspect-oriented programming (AOP) in Objective-C using a block. Here are my questions on how to implement this.

Further question 1:

How to implement a variational function that takes up many blocks described above and ends with nil , and I could call this function with many blocks until I encounter zero? It will be like this:

 @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 

Further question 2:

What if the recursive block has a return value?


Additional C language question:

Is it possible to declare a function C that takes one parameter, which is a pointer to the function C, and that the pointer function of the function C also takes another pointer to the function C?

+8
objective-c aop block recursion
source share
2 answers

which may be similar that you are looking for:

 typedef void (^Block)(id); 

literally, this will trigger an infinite recursive loop:

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

however, the parameter can be any id not only the same Block , but it represents how you pass the same block as the parameter for the same block.

therefore there will be an idea.

+11
source share

This is much easier to do by capturing the block in the __block link. In fact, declaring generic types in C is simply not supported. So this could be the only solution?

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

Please note that if you plan to send this block asynchronously, you must copy it before the destination (this may no longer be necessary in ARC):

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

All Articles