SpaceDog SpaceDog - 8 months ago 88
Objective-C Question

Avoiding the "capturing self strongly in this block is likely to lead to a retain cycle" message

every time I have to use a global var or property inside a block like this: = ^(){
if (isItSaving == NO) {
[self saveMyFile];

I have to rewrite this like

BOOL *iis = isItSaving;
id myself = self; = ^(){
if (iis == NO) {
[myself saveMyFile];

or Xcode will complain "capturing self strongly in this block is likely to lead to a retain cycle...

It complains even about BOOL variables?

Redeclaring everything before a block appears to be a lame solution.

Is this the correctly way? Is there an elegant way?

This stuff is ugly. I am using ARC.


The problem only occurs when referencing self from within the block, explicitly or implicitly. There's no warning emitted when accessing global variables.

In your case you probably accessed a (boolean) ivar. Accessing the ivar implicitly uses self, that's why the compiler is warning you (correctly) about a retain cycle.

The common way to fix the retain cycle is:

typeof(self) __weak weakSelf = self; = ^() {
    typeof(weakSelf) __strong strongSelf = weakSelf;
    if (strongSelf != nil && ! strongSelf->isItSaving) {
        [strongSelf saveMyFile];

... and, yes, that's a bit of an ugly part of blocks.