I'd like to recursively call a block from within itself. In an obj-c object, we get to use "self", is there something like this to refer to a block instance from inside itself?
4 Answers
Fun story! Blocks actually are Objective-C objects. That said, there is no exposed API to get the self
pointer of blocks.
However, if you declare blocks before using them, you can use them recursively. In a non-garbage-collected environment, you would do something like this:
__weak __block int (^block_self)(int);
int (^fibonacci)(int) = [^(int n) {
if (n < 2) { return 1; }
return block_self(n - 1) + block_self(n - 2);
} copy];
block_self = fibonacci;
It is necessary to apply the __block
modifier to block_self
, because otherwise, the block_self
reference inside fibonacci
would refer to it before it is assigned (crashing your program on the first recursive call). The __weak
is to ensure that the block doesn't capture a strong reference to itself, which would cause a memory leak.

- 134,922
- 42
- 253
- 328
-
1Excellent answer. the __block modifier would have taken me awhile to figure out on my own. Thanks a ton! Rep to you! – Arlen Anderson Jan 28 '11 at 04:02
-
3If you pass it to a function that will end up copying it (such as `dispatch_async()`), you also need to copy the block in the scope of the assignment. – Jens Ayton Jan 28 '11 at 10:22
-
2This code will leak, even if you have a termination condition. Add a countdown variable and run it through Instruments leak checker to see. Also, the compiler will issue the following warning if you have the right warnings turned on: "Capturing 'myBlock' in this block is likely to lead to a retain cycle" – Karl May 11 '12 at 16:43
-
@Karl, I guess I was using garbage collection when I wrote this. What is your solution then? – zneak May 11 '12 at 18:18
-
I'll take another stab at it tonight or tomorrow. I've only managed to come up with an ugly hack so far. – Karl May 11 '12 at 22:48
-
@Karl any interesting developments in the last couple of years? – Stavash May 25 '14 at 11:19
-
@Stavash, see answer below. – zneak May 25 '14 at 16:56
The following recursive block code will compile and run using ARC, GC, or manual memory management, without crashing, leaking, or issuing warnings (analyzer or regular):
typedef void (^CountdownBlock)(int currentValue);
- (CountdownBlock) makeRecursiveBlock
{
CountdownBlock aBlock;
__block __unsafe_unretained CountdownBlock aBlock_recursive;
aBlock_recursive = aBlock = [^(int currentValue)
{
if(currentValue >= 0)
{
NSLog(@"Current value = %d", currentValue);
aBlock_recursive(currentValue-1);
}
} copy];
#if !__has_feature(objc_arc)
[aBlock autorelease];
#endif
return aBlock;
}
- (void) callRecursiveBlock
{
CountdownBlock aBlock = [self makeRecursiveBlock];
// You don't need to dispatch; I'm doing this to demonstrate
// calling from beyond the current autorelease pool.
dispatch_async(dispatch_get_main_queue(), ^
{
aBlock(10);
});
}
Important considerations:
- You must copy the block onto the heap manually or else it will try to access a nonexistent stack when you call it from another context (ARC usually does this for you, but not in all cases. Better to play it safe).
- You need TWO references: One to hold the strong reference to the block, and one to hold a weak reference for the recursive block to call (technically, this is only needed for ARC).
- You must use the __block qualifier so that the block doesn't capture the as-yet unassigned value of the block reference.
- If you're doing manual memory management, you'll need to autorelease the copied block yourself.

- 14,434
- 9
- 44
- 61
-
This wouldn't work in ARC, but what about ```copy] autorelease]``` instead of just copy, so you don't have to call release inside the block? For ARC maybe doing ```aBlock = nil``` after calling ```aBlock(10);``` ? – Javier Soto May 13 '12 at 05:44
-
Actually, upon revisiting this solution, it turns out that holding the reference inside the block would cause a leak if the block didn't get called. I've now updated the answer so that it works properly whether you call it or not. – Karl May 13 '12 at 16:28
-
I have a problem that adds a layer of complexity to this, but I'm not entirely sure my problem is solvable. I'd like to be able to retry API calls through AFNetworking. I think this pastebin simplifies and illustrates the problem. http://pastebin.com/xRPJuckZ The unsafe_unretained recursive block is called from inside another block inside itself, and calling it there leads to a bad access exception. Would you have any idea how to solve this? – Matt Foley Apr 03 '14 at 21:56
-
aBlock is the one holding the strong reference, so once it falls out of scope (in the calling function you returned it to), it gets released, and your inner unsafe_unretained reference becomes invalid. You would need to devise a way to hold the strong reference until you're sure you don't need it anymore. You might be able to do "__block RetryAPICall aBlock", and then conditionally set it to nil inside the block. I'm not sure if that will work, though. – Karl Apr 11 '14 at 11:38
You have to declare the block variable as __block
:
typedef void (^MyBlock)(id);
__block MyBlock block = ^(id param) {
NSLog(@"%@", param);
block(param);
};

- 242,470
- 58
- 448
- 498
-
@Joe Blow [`__block` specifically is a keyword](http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6). – Dave DeLong Jan 28 '11 at 08:07
-
There is no self
for blocks (yet). You can build one like this (assuming ARC):
__block void (__weak ^blockSelf)(void);
void (^block)(void) = [^{
// Use blockSelf here
} copy];
blockSelf = block;
// Use block here
The __block
is needed so we can set blockSelf
to the block after creating the block. The __weak
is needed because otherwise the block would hold a strong reference to itself, which would cause a strong reference cycle and therefore a memory leak. The copy
is needed to make sure that the block is copied to the heap. That may be unnecessary with newer compiler versions, but it won't do any harm.

- 10,514
- 2
- 35
- 44