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
Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
提问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:
我想我的问题是:
- Do/should I care?
- Should I declare myTimer as a property?
- 我应该/我应该关心吗?
- 我应该将 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登录工具包
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
结果
回答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: true或inhibit_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_SELF为YES每当pod install执行命令时。对此的解决方案是通过执行“
Once reverted just execute ”将XCODEPROJ恢复到较早的版本 1.5.1,并且该标志将始终设置为“NO”。sudo gem install xcodeproj -v 1.5.1pod install


