Common block-related retain cycles in iOS

mysticriver
Dec 22, 2020

Summarize some common block-related retain cycle patterns.

  1. retain local variables
- (void)presentNewViewController {
UIViewController *newVC = [UIViewController new];
newVC.completion = ^ {
newVC.title = @"some_title_after_completion";
};
[self presentViewController: newVC animated: YES];
}

In the above example, the retain cycle is newVC -> completion -> newVC

2. Superficial class method

@implementation CallingViewController {
- (void)loadData {
[DataSource fetchDataWithCompletion: ^{
self.dataReady = YES;
}]; }
}
// However, in the data source it uses instance method instead of class method as it appears.
// in DataSource
- (void)fetchDataWithCompletion:(void(^)(id data, NSError *error))completion {
[[NetworkingLayer sharedInstance] getRequest:request completion:completion];
}

In the above example, CallingViewController loadData method scope -> NetworkingLayer instance -> completionBlock -> CallingViewController

Rule of thumb

  1. Always use weakSelf with block (for pattern 2)
  2. Double check local variable references

--

--