iosobjective-cblockretain-cycle

break retain cycle in a block nested in another block


Sometimes I use a block nested in another block, here is my code

- (void)test {
    __weak typeof(self) weakSelf = self;
    [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf.dataSource disposalData:^{
        // here is the strongSelf ok? do I have to do something to avoid retain cycle?
            [strongSelf updateUI];
        }];
    }];
}
- (void)updateUI {
    
}

I doubt the inner block still has a retain cycle?

    [strongSelf.dataSource disposalData:^{
        [strongSelf updateUI];
    }];

my question is what is the correct way to break the retain cycle in such situation?


here is the additional discussion, as many friend mentioned about this, if I remove __strong typeof(weakSelf) strongSelf = weakSelf;, the inner block has no retain cycle? Is it perfectly correct?

- (void)test {
    __weak typeof(self) weakSelf = self;
    [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
        [weakSelf.dataSource disposalData:^{
            [weakSelf updateUI];
        }];
    }];
}
- (void)updateUI {
    
} 

Solution

  • I think you can just create new strong reference inside nested block, like this:

    - (void)test {
        __weak typeof(self) weakSelf = self;
        [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf.dataSource disposalData:^{
                __strong typeof(weakSelf) strongSelf = weakSelf; // <- new strong ref
                [strongSelf updateUI];
            }];
        }];
    }
    

    It will override the first strongSelf in the nested block scope. And it will be only alive during the execution of the nested block without strong reference cycle created. I think so =)