Last active
April 13, 2022 16:21
-
-
Save mx4492/8033600 to your computer and use it in GitHub Desktop.
Recursive Blocks in Objective C (under ARC)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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