ARC behavior within a recursive block

后端 未结 2 2067
情书的邮戳
情书的邮戳 2021-01-19 01:51

I\'ve made these two utility funcions:

+ (void)dispatch:(void (^)())f afterDelay:(float)delay {
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t         


        
2条回答
  •  感动是毒
    2021-01-19 02:20

    _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];
    }
    

提交回复
热议问题