Block implicitly retains 'self'; - but is it intended behaviour?

Given:

- (void)bobIsYourUncle {
   ^{score.alpha = 0.0;}();
}

Where score is an instance variable that instance variable is accessed via self. Because the block may be equeued somewhere and executed later, the block retains self when the block is created.

Because ivar access invisibly dereferences through self, that implicit retain is kinda not apparent in the code. The rather ugly suggestion by the compiler of adding self-> in front of the ivar makes it, at least, obvious that self is captured by the block.

So, yes, it is the correct behavior. And, yes, it is sometime desired. You could avoid it by grabbing the ivar's value before the block is created (in a local variable), but you must also know that doing so changes the time at which the ivar's value is obtained and that could cause a behavior change.


This warning about implicit references to self is useful because in the absence of that, when glancing at code it isn't always obvious which blocks have the risk of introducing strong reference cycles and which don't. By encouraging the programmer to make these self references explicit (such as is required in safe programming languages like Swift), you end up with code where you can plainly see whether a strong reference cycle is a potential issue or not.

So, I'd encourage you to leave the warning turned on but go ahead and make those implicit self references (the ivars) explicit with self-> or, if using properties, self., as advised by the first answer you referenced.

Then you can review those individual uses of self closures and make sure they don't introduce any real risk of strong reference cycles. And if they do, you can adopt the weakSelf or weakSelf/strongSelf patterns as appropriate.