I'm working on a project where I see a lot of code that uses completion blocks with __strong
references for a __weak
variable to perform operations on that object in the completion block. We want to avoid an EXEC_BAD_ACCESS crash if the completion block fires after the view is deallocated, and also not retain the view controller until the completion block finishes. Here's some sample pseudo code:
__weak UIViewController *weakSelf = self;
[[DataManager sharedInstance] dataWithCompletionBlock:^(id data) {
if (!weakSelf) return;
__strong UIViewController *strongSelf = weakSelf;
strongSelf.data = data;
}];
The way I understand memory management, weakSelf
, if it passes the conditional check, will not be deallocated until the end of the run loop at the earliest, so the __strong
reference is unnecessary. Instead, the __weak
reference can be safely acted on since there is a conditional already checking for it to prevent a EXEC_BAD_ACCESS crash. A __strong
reference should only be necessary if we had something like calling an async method with its own completion block that needed the view controller not to be deallocated.
What is the proper usage here? Is __strong
necessary? or is it safe to simply access the __weak
variable? Am I correct in my understanding of how this works?