Search code examples
iosrecursionautomatic-ref-countingblock

ios recursive call with block leaks memory


I am calling a function recursively from completion block which increases the memory foot print, this most probably is leading to a block retain cycle,following is the code:

- (void)tick {

   if (counter > counterLimit) {
      [self finish];
      return;
   }

   counter++;

   context = [[Context alloc] init];

   //this is executed in another thread 
   [self.executer computeWithContext:(Context*)context completion:^(NSDictionary *dictionary, Context *context_)
   {

      [self handleResponse];

      [self tick];

   }];
}

Solution

  • self is owning executer, executer is owning the block, the block captures self strongly (same effect as owning). you have a retain cycle.

    create a weak reference for self and use that in the block exclusively.

    - (void)tick {
       // ...
    
       __weak typeof(self) weakSelf = self;
       [self.executer computeWithContext:(Context*)context completion:^(NSDictionary *dictionary, Context *context_)
       {
          typeof(weakSelf) strongSelf = weakSelf;
          if(strongSelf) { // ensure the receiver is still there to receive
              [strongSelf handleResponse];
              [strongSelf tick];
          }    
       }];
    }