Sup guys,
I\'m trying to do a function that calls itself but by putting everything on one block,
As you can see, the following function is intended to be cal
You have to declare your block itself as a block variable:
__block void (^_test_closure)();
_test_closure = ^{
NSLog(@"Running...");
if ((arc4random() % 100) > 50) {
_test_closure();
}
}
_test_closure();
It works with XCode 5 - no warnings, no retain cycles:
typedef void(^blockT)();
blockT block1;
blockT __block block1recursive;
block1recursive = block1 = ^(){
block1recursive();
};
block1();
Recursion and blocks is tricky. Because a block captures all variables passed in, the variable _test_closure
is not initialized yet (and clang should give you a warning:
Block pointer variable '_test_closure' is uninitialized when captured by block
).
There are several ways you can get around this, but the most obvious & simplest is to just make the block itself a __block
variable (what @H2CO3 said). This allows the block to be weak-linked
almost, so that when you call it again, it is properly initialized.
Another option you have is making the block a global or static, like this:
// outside of 'main', thus being a global variable
void (^blockRecurse)(int) = ^(int level) {
if (level < 0)
return;
NSLog(@"Level: %i", level);
blockRecurse(--level);
};
int main()
{
@autoreleasepool {
blockRecurse(10);
}
}
This means it's not being captured by the block, but instead it's referencing the global / static variable, which can be changed by all code equally.