1

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 {
    
} 
childrenOurFuture
  • 1,889
  • 2
  • 14
  • 23
  • In this case, is there a reason to actually create `strongSelf` from `weakSelf` instead of using `weakSelf` directly inside the blocks? – Sulthan Jul 17 '21 at 10:26
  • thx your advice, I don't really understand this part.could you tell me the reason and what the solution? thx a lot. – childrenOurFuture Jul 19 '21 at 01:15
  • Creating `strongSelf` (at the beginning of the block) ensures that `self` exists for the entire execution time of the block (if `self` exists at the moment of `strongSelf` creation). In some cases, this can be very important. You can use `weakSelf` directly inside the block without strong reference cycle creation, but this is unsafe. I think so =) – Artem Jul 19 '21 at 08:35
  • @Artem, yes, that why I use the strongSelf. but my question is not about here ,so I just make it simple. my key concern is about the nested block, if there is only a block, simple to use a weak reference to break the retain cycle, it's ok, but there is a inner nested block, does the nested block has the retain cycle? and how to deal with it. – childrenOurFuture Jul 19 '21 at 08:43
  • @childrenOurFuture I think that no, there is no strong reference cycle (in your last snippet), because the nested block captured only `__weak` reference (`weakSelf`). But in your fist snippet strong reference cycle was created, because the nested block captured `__strong` reference (`strongSelf`), created in the external block. But only after the `strongSelf` has been created during the execution of the external block. I thing so =) – Artem Jul 19 '21 at 10:34
  • @Artem thx, I agree with you, so how to deal with it in the first snippet, if I expect it works correctly. make a weak reference again? do you have any idea? – childrenOurFuture Jul 19 '21 at 10:51
  • @childrenOurFuture In your place, I would override `strongSelf` in the nested block and then use it. As I said in my answer =) – Artem Jul 19 '21 at 11:16
  • @Artem much appreciated – childrenOurFuture Jul 19 '21 at 12:09

1 Answers1

1

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 =)

Artem
  • 373
  • 2
  • 6
  • @SeaSpell I think that it is necessary to override `strongSelf` in the nested block because if you will use the `strongSelf` (defined as `__strong` reference in the outer block) in the nested block, then the nested block will capture `self` by strong reference and therefore retain cycle will be created. `self` will retain nested block and vice versa. I think so =) – Artem Jul 19 '21 at 17:32