鉴于以下内容:
- (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属性来修复它,但我想确保在我这样做之前得到更好的理解。
用myTimer
替换self->myTimer
会修复你的警告。
当您在代码中使用iVar _iVar
时,编译器将用self->_iVar
替换代码,如果您在块中使用它,则块将捕获self而不是iVar本身。警告只是为了确保开发人员了解此行为。
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
对于那些因为Bolts
/ FBSDKCoreKit
/ FBSDKLoginKit
而得到这些警告的人,你应该避免瓦西里的答案,而是沉默那些特定依赖的警告。
提及每个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!
。
这解决了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];
}
});
}
最近我遇到了同样的问题,@ 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。