鉴于以下内容:
- (void) someMethod
{
dispatch_async(dispatch_get_main_queue(), ^{
myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
target: self
selector: @selector(doSomething)
userInfo: nil
repeats: NO];
});
}
在私有界面中声明myTimer的地方:
@interface MyClass()
{
NSTimer * myTimer;
}
@end
如何修复以下警告:
Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
从我到目前为止发现的内容来看,大多数建议都涉及到如下内容:
- (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];
});
}
除此之外,myTimer是一个ivar,意味着wself
无法访问任何属性。
我想我的问题是:
我在代码中使用了很多ivars。我刚刚将-Weverything
标志添加到我的项目中,以查看是否可以找到任何潜在问题,这是迄今为止最常见的警告。我没有问题,并通过制作我的ivars属性来修复它,但我想确保在我这样做之前得到更好的理解。
答案 0 :(得分:63)
Xcode:9.2,10.2
我有快速的项目。使用Objective-C pod时出现警告Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
:
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO
添加到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
答案 1 :(得分:58)
按myTimer
替换self->myTimer
会修复您的警告。
当您在代码中使用iVar _iVar
时,编译器将用self->_iVar
替换代码,如果您在块中使用它,则块将捕获self而不是iVar本身。警告只是为了确保开发人员理解这种行为。
答案 2 :(得分:15)
对于那些因Bolts
/ FBSDKCoreKit
/ FBSDKLoginKit
而收到这些警告的人,您应该避免使用Vasily的答案,而是将这些特定依赖项的警告静音。 / p>
提及每个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
或者通过添加到您的Podfile中来静音所有pod:
inhibit_all_warnings!
您仍会收到有关自己代码的警告。没有那些可能会在某些时候出现问题,这就是为什么我认为它是一个更好的解决方案。
下次更新Facebook sdk时,看看您是否可以删除inhibit_warnings: true
或inhibit_all_warnings!
。
答案 3 :(得分: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];
}
});
}
答案 4 :(得分:2)
最近我遇到了同样的问题,@ Vasily Bodnarchuk的回答似乎很有帮助。
但是在持续集成环境中,无法在运行时将CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
标志更改为NO
。
因此,为了通过检查Cocoapods安装的所有依赖GEMS来解决问题,并且发现gem XCODEPROJ版本1.5.7在执行CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
命令时将YES
设置为pod install
。
解决方案是通过执行sudo gem install xcodeproj -v 1.5.1
将 XCODEPROJ 恢复到早期版本1.5.1
一旦恢复,只需执行pod install
,该标志将始终设置为NO。