简体   繁体   中英

Retain cycles when using ARC and blocks

From my understanding when an object method receives a block as a completion argument I can send "self" in the block:

[object doMethodWithCompletion:^{
  [self doSomethingWhenThisMethodCompletes]
}];

but if this object "retains" the block (saves it for future use) I should send a "weak" copy of myself:

__weak __typeof__(self) weakSelf = self;
object.savedBlock = ^{
  [weakSelf doSomethingWhenThisBlockIsCalledFromWithinObject];
};

but I have also seen variants such as:

__weak __typeof__(self) weakSelf = self;
object.savedBlock = ^{
  __typeof__(weakSelf) strongSelf = weakSelf;
  [strongSelf doSomethingWhenThisBlockIsCalledFromWithinObject];
};

and I am not clear on why/when to do this last variant

Creating a strong reference inside the block makes sure that if the block runs, the object is not deallocated halfway through the block, which could lead to unexpected, hard to debug behaviour.

typeof(self) weakSelf = self;
[anObject retainThisBlock:^{
    [weakSelf foo];
    // another thread could release the object pointed to by weakSelf
    [weakSelf bar];
}];

Now [weakSelf foo] would run, but [weakSelf bar] wouldn't because weakSelf is now nil . If you create a strong reference inside the block, the object can't be released until the block returns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM