Search code examples
objective-cmacosobjective-c-blocks

Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior


Given the following:

- (void) someMethod
{
    dispatch_async(dispatch_get_main_queue(), ^{
        myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
                                                           target: self
                                                         selector: @selector(doSomething)
                                                         userInfo: nil
                                                          repeats: NO];
    });
}

Where myTimer is declared in a private interface:

@interface MyClass()
{
    NSTimer * myTimer;
}
@end

How would one fix the following warning:

Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior

From what I have found so far, most suggestions involve putting something such as:

- (void) someMethod
{
    __typeof__(self) __weak wself = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        wself.myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
                                                           target: self
                                                         selector: @selector(doSomething)
                                                         userInfo: nil
                                                          repeats: NO];
    });
}

Except, that myTimer is an ivar, meaning wself does not have access to any properties.

I guess my questions are:

  1. Do/should I care?
  2. Should I declare myTimer as a property?

I use ivars quite a bit through my code. I just added the -Weverything flag to my project to see if I can find any underlying issues and this is by far the most common warning. I have no problem going though and fixing it by making my ivars properties, but I want to make sure I get a better understanding before I do that.


Solution

  • Replacing myTimer by self->myTimer would fix your warning.

    When you use an iVar _iVar in the code, the compiler will replace the code by self->_iVar, and if you use it inside a block, the block will capture self instead of the iVar itself. The warning is just to make sure that the developer understand this behaviour.