Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement recursive blocks?

I want to declare a block type which take one parameter that is the same block type. It's just like this:

typedef void (^BlockInBlock) (BlockInBlock block);

I know the declaration is not valid. But I wonder if there is any possible way to implement recursive block which take just one parameter that is the same block type.


I'm trying finding a way to implement aspect-oriented programming (AOP) in Objective-C using block. Here are my questions about how to implement that.

Further Question 1:

How to implement a variadic function which takes many Blocks I described above and is ended up with nil, and I could invoke that function with many blocks until meets nil? It would 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 Question about C language:

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

like image 742
Xaree Lee Avatar asked Sep 13 '13 17:09

Xaree Lee


People also ask

What is a recursive block?

Some equation systems are said to be “block recursive,” meaning that the recursive or triangular property applies only to blocks made up of subsets of the equations in the model.

How do you make a recursive function in Javascript?

A function that calls itself is called a recursive function. The syntax for recursive function is: function recurse() { // function code recurse(); // function code } recurse(); Here, the recurse() function is a recursive function.


2 Answers

that may be similar you are looking for:

typedef void (^Block)(id);

literally, it will cause an infinite recursive loop:

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

_block(_block);

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

so, that would be the idea.

like image 141
holex Avatar answered Oct 21 '22 14:10

holex


It is much easier to do this by capturing the block in an __block reference. Actually, forward declaration of generic types in C are simply not supported. So, this may be the only solution?

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

Note that if you are planning on dispatching that block asynchronously, you must copy it prior to assignment (this might no longer be necessary under ARC):

__block void(^strawberryFields)();
strawberryFields = [^{ strawberryFields(); } copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
               strawberryFields);
like image 34
bbum Avatar answered Oct 21 '22 13:10

bbum