I\'ve made these two utility funcions:
+ (void)dispatch:(void (^)())f afterDelay:(float)delay {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t
_f needs be a strong reference, because otherwise in ARC the block that gets assigned to it may immediately disappear, because there are no strong references to it.
At the same time, the block needs to access a pointer to itself, and, as you discovered, this must be done with a __block variable. A strong reference from the block to itself will cause a retain cycle, so this must be a weak reference.
Therefore, you need two variables, one strong, and one weak:
+ (void)dispatch:(void (^)())f withInterval:(float)delay {
__block __weak void (^_f_weak)() = nil; // a weak __block variable for the block to capture
void (^_f)() = nil; // a strong variable to hold the block itself
_f_weak = _f = ^{ // both variables will point to the block
f();
[self dispatch:_f_weak afterDelay:delay];
};
[self dispatch:_f afterDelay:delay];
}