objective-c 块隐式保留“自我”;明确提及“自我”以表明这是预期行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21577711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:11:28  来源:igfitidea点击:

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

objective-cmacosobjective-c-blocks

提问by Kyle

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:

在私有接口中声明 myTimer 的地方:

@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 wselfdoes not have access to any properties.

除了 myTimer 是一个 ivar,这意味着wself无法访问任何属性。

I guess my questions are:

我想我的问题是:

  1. Do/should I care?
  2. Should I declare myTimer as a property?
  1. 我应该/我应该关心吗?
  2. 我应该将 myTimer 声明为属性吗?

I use ivars quite a bit through my code. I just added the -Weverythingflag 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.

我通过我的代码大量使用 ivars。我刚刚将-Weverything标志添加到我的项目中,以查看是否可以找到任何潜在问题,这是迄今为止最常见的警告。我通过制作我的 ivars 属性来修复它没有问题,但我想确保在我这样做之前我得到了更好的理解。

回答by Vasily Bodnarchuk

Details

细节

Xcode: 9.2, 10.2, 11.0 (11A420a)

Xcode: 9.2, 10.2, 11.0 (11A420a)

Warnings in Objective-C Pods

Objective-C Pod 中的警告

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

我有一个快速的项目。Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior当我使用 Objective-C pod 时出现警告:

  • Bolts
  • FBSDKCoreKit
  • FBSDKLoginKit
  • 螺栓
  • FBSDKCoreKit
  • FBSDK登录工具包

enter image description here

在此处输入图片说明

Solution 1 (manual)

解决方案 1(手动)

CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO

Solution 2 (automatic)

解决方案 2(自动)

Add to the end of your Podfile:

添加到 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

在此处输入图片说明

回答by bsarr007

Replacing myTimerby self->myTimerwould fix your warning.

替换myTimerbyself->myTimer将解决您的警告。

When you use an iVar _iVarin 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.

当您_iVar在代码中使用 iVar时,编译器会将代码替换为self->_iVar,如果您在块中使用它,则块将捕获 self 而不是 iVar 本身。警告只是为了确保开发人员理解这种行为。

回答by Nycen

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.

对于那些因为Bolts/ FBSDKCoreKit/而收到这些警告的人FBSDKLoginKit,您应该避免 Vasily 的回答,而是将这些特定依赖项的警告静音。

Option 1

选项1

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

提及每个 Pod 而不仅仅是 FacebookCore 并添加 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

选项 2

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

或者通过将以下内容添加到您的 Podfile 来使所有 Pod 静音:

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: trueor inhibit_all_warnings!.

下次更新 Facebook sdk 时,看看是否可以删除inhibit_warnings: trueinhibit_all_warnings!

回答by Pooja Gupta

This fixes my problem for Xcode 9.3

这解决了我的 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];
       }

   });
}

回答by bhuvan

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

最近我遇到了同样的问题,@Vasily Bodnarchuk 的回答似乎很有帮助。

However in Continuous integration environments its not possible to change the CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELFflag to NOat 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_SELFto YESwhenever pod installcommand is executed. The solution for this is reverting the XCODEPROJto earlier version 1.5.1 by executing sudo gem install xcodeproj -v 1.5.1Once reverted just execute pod installand the flag will be set to NO always.

但是,在持续集成环境中,不可能在运行时将CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF标志更改为NO。因此,为了隔离该问题,我尝试通过检查 Cocoapods 安装的所有相关 GEMS 并发现 gem XCODEPROJ 版本 1.5.7 将 设置CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELFYES每当pod install执行命令时。对此的解决方案是通过执行“ Once reverted just execute ”将XCODEPROJ恢复到较早的版本 1.5.1,并且该标志将始终设置为“NO”。sudo gem install xcodeproj -v 1.5.1pod install