Skip to content

Instantly share code, notes, and snippets.

@mx4492
Last active April 13, 2022 16:21
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mx4492/8033600 to your computer and use it in GitHub Desktop.
Save mx4492/8033600 to your computer and use it in GitHub Desktop.
Recursive Blocks in Objective C (under ARC)
#include <stdio.h>
/**
This only works if the block in question is called synchronously.
*/
void try0() {
typedef void(^RecursiveBlock)();
__block int i = 5;
__weak __block RecursiveBlock weakBlockBlock;
RecursiveBlock block = ^{
printf("i: %d\n", i);
i -= 1;
if (i > 0) {
weakBlockBlock();
}
};
weakBlockBlock = block;
block();
}
void try1() {
typedef void (^RecursiveBlock)(id continuation);
__block int i = 5;
RecursiveBlock block = ^(RecursiveBlock continuation){
printf("i: %d\n", i);
i -= 1;
if (i > 0) {
continuation(continuation);
}
};
block(block);
}
/**
This is the probably the most natural of the given approaches.
Unfortunately, this results in a spurious warning from the static analyzer.
@see http://stackoverflow.com/a/13091475/141220
*/
void try2() {
typedef void (^RecursiveBlock)();
__block int i = 5;
__block RecursiveBlock block = ^(){
printf("i: %d\n", i);
i -= 1;
if (i > 0) {
block();
} else {
block = nil;
}
};
block();
}
int main(int argc, const char * argv[]){
@autoreleasepool {
try0();
try1();
try2();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment