2
votes

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.
  }
}
1
Before you go much further, you should make sure that you deeply understand what a retain cycle actually is. Blindly trying to avoid them will make your app crash.Catfish_Man
Well, first of all, your second code shouldn't compile, because you've declared that the C++ lambda doesn't capture any variables, yet it uses self, which is a local variable from the outside.newacct

1 Answers

4
votes

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.