Search code examples
automatic-ref-countingblockobjective-c++

Do I need to use a weak pointer when using C++ `function` blocks (as opposed to Objective C blocks)


If you capture a strong reference to self under ARC in an objective-C style block, you need to use a __weak pointer to avoid an ARC "retain cycle" problem.

// Right way:
- (void)configureBlock {
  XYZBlockKeeper * __weak weakSelf = self;
  self.block = ^{
    [weakSelf doSomething];   // capture the weak reference
                              // to avoid the reference cycle
  }
}

I really don't know what a retain cycle is, but this answer describes it a bit. I just know you should use a __weak pointer for Objective-C style blocks. See Avoid Strong Reference Cycles when Capturing self.

But my question is, do I need to create a weak pointer when capturing self under a C++ <functional> block?

- (void)configureBlock {
  self.block = [self](){
    [self doSomething]; // is this ok? It's not an objective C block.
  }
}

Solution

  • C++ lambdas can captured variables either by value or by reference (you choose when you declare the lambda how to capture each variable).

    Capturing by reference is not interesting, because references to local variables become invalid after you leave the variable's scope anyway, so there is no memory management issues at all.

    Capturing by value: if the captured variable is an Objective-C object pointer type, then it gets interesting. If you are using MRC, nothing happens. If you are using ARC, then yes, the lambda "retains" captured variables of object pointer type, as long as they are __strong (not __weak or __unsafe_unretained). So, yes, it would create a retain cycle.