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

Objective CMacosObjective C-Blocks

Objective C Problem Overview


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.

Objective C Solutions


Solution 1 - Objective C

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 the the developer understand this behaviour.

Solution 2 - Objective C

Details

Xcode: 9.2, 10.2, 11.0 (11A420a)

Warnings in Objective-C Pods

I have swift project. Warning Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior appears when I use Objective-C pods:

  • Bolts
  • FBSDKCoreKit
  • FBSDKLoginKit

enter image description here

Solution 1 (manual)

CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO

Solution 2 (automatic)

> Add to the end of your Podfile:

post_install do |installer|
      installer.pods_project.targets.each do |target|
           target.build_configurations.each do |config|
                config.build_settings['CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF'] = 'NO'
           end
      end
 end

Results

enter image description here

Solution 3 - Objective C

For those of you getting these warnings because of Bolts/FBSDKCoreKit/FBSDKLoginKit, you should avoid Vasily's answer and instead silence the warnings for those specific dependencies.

Option 1

Mention each pods instead of just FacebookCore and add inhibit_warnings: true

pod 'FacebookCore', inhibit_warnings: true
pod 'Bolts', inhibit_warnings: true
pod 'FBSDKCoreKit', inhibit_warnings: true
pod 'FBSDKLoginKit', inhibit_warnings: true

Option 2

Or silence all pods, by adding to your Podfile this:

inhibit_all_warnings!

Conclusion

You'll still get warnings for your own code. Not getting those could be problematic at some point, that's why I believe it's a better solution.

Next time you update the Facebook sdk, see if you can remove the inhibit_warnings: true or inhibit_all_warnings!.

Solution 4 - Objective C

This fixes my problem for Xcode 9.3

- (void) someMethod{

    __weak MyClass *wSelf = self;

    dispatch_async(dispatch_get_main_queue(), ^{
    
    MyClass *sSelf = wSelf;
    if(sSelf != nil){
        wself.myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
                                                       target: self
                                                     selector:@selector(doSomething)
                                                     userInfo: nil
                                                      repeats: NO];
       }
   
   });
}

Solution 5 - Objective C

Recently I faced the same issue and @Vasily Bodnarchuk answer seems to be helpful.

However in Continuous integration environments its not possible to change the CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF flag to NO at run time. So in order to isolate the issue i tried by checking all the dependent GEMS installed by Cocoapods and figured out that gem XCODEPROJ version 1.5.7 sets the CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF to YES whenever pod install command is executed. The solution for this is reverting the XCODEPROJ to earlier version 1.5.1 by executing sudo gem install xcodeproj -v 1.5.1 Once reverted just execute pod install and the flag will be set to NO always.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKyleView Question on Stackoverflow
Solution 1 - Objective Cbsarr007View Answer on Stackoverflow
Solution 2 - Objective CVasily BodnarchukView Answer on Stackoverflow
Solution 3 - Objective CArnaudView Answer on Stackoverflow
Solution 4 - Objective CPooja GuptaView Answer on Stackoverflow
Solution 5 - Objective CbhuvanView Answer on Stackoverflow