Блок неявно сохраняет "я"; прямо укажите "я", чтобы указать, что это предполагаемое поведение
Учитывая следующее:
- (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
не имеет доступа к каким-либо свойствам.
Я думаю, мои вопросы:
- У меня/мне все равно?
- Должен ли я объявлять myTimer как свойство?
Я использую ivars совсем немного через свой код. Я просто добавил флаг -Weverything
в свой проект, чтобы узнать, могу ли я найти какие-либо основные проблемы, и это, безусловно, самое распространенное предупреждение. У меня нет проблем, хотя и исправляю его, создавая свойства ivars, но я хочу убедиться, что я получу лучшее понимание, прежде чем я это сделаю.
Ответы
Ответ 1
Замена myTimer
на self->myTimer
исправит ваше предупреждение.
Когда вы используете iVar _iVar
в коде, компилятор заменит код на self->_iVar
, и если вы используете его внутри блока, блок будет захватывать сам, а не сам iVar. Предупреждение только для того, чтобы разработчик понял это поведение.
Ответ 2
Подробнее
Xcode: 9,2, 10,2, 11,0 (11A420a)
Предупреждения в модулях Objective-C
У меня быстрый проект. Предупреждение Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
появляется при использовании модулей Objective C:
- Болты
- FBSDKCoreKit
- FBSDKLoginKit
Решение 1 (ручное)
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO
Решение 2 (автоматическое)
Добавьте в конец своего подфайла:
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
Результаты
Ответ 3
Для тех из вас, кто получает эти предупреждения из-за Bolts
/FBSDKCoreKit
/FBSDKLoginKit
, вы должны избегать ответа Василия и вместо этого FBSDKLoginKit
предупреждения для этих конкретных зависимостей.
Опция 1
Упомяните каждый комплект, а не только FacebookCore и добавьте inhibit_warnings: true
pod 'FacebookCore', inhibit_warnings: true
pod 'Bolts', inhibit_warnings: true
pod 'FBSDKCoreKit', inhibit_warnings: true
pod 'FBSDKLoginKit', inhibit_warnings: true
Вариант 2
Или отключите все стручки, добавив в свой подфайл следующее:
inhibit_all_warnings!
Вывод
Вы по-прежнему будете получать предупреждения для своего собственного кода. Не получилось, что в какой-то момент это может быть проблематично, поэтому я считаю это лучшим решением.
В следующий раз, когда вы обновите sdk Facebook, посмотрите, можете ли вы удалить inhibit_warnings: true
или inhibit_all_warnings!
,
Ответ 4
Это исправляет мою проблему для 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];
}
});
}
Ответ 5
Недавно я столкнулся с той же проблемой, и ответ @Vasily Bodnarchuk кажется полезным.
Однако в средах с непрерывной интеграцией невозможно изменить флаг CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
на NO
во время выполнения. Поэтому, чтобы изолировать проблему, которую я попытался проверить все зависимые GEMS, установленные Cocoapods, и выяснил, что gem XCODEPROJ версия 1.5.7 устанавливает CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
в YES
когда выполняется команда pod install
. Решением для этого является возврат XCODEPROJ к более ранней версии 1.5.1 путем выполнения sudo gem install xcodeproj -v 1.5.1
После того, как вы вернули, просто выполните pod install
и флаг будет всегда установлен как NO.
Ответ 6
Ребята, пожалуйста, не заглушайте предупреждение, как уже упоминали другие!
Это указывает на проблему в вашем коде с сохранением объекта, которая может привести к серьезным проблемам с памятью, особенно когда этот объект большой. У меня были сохранены целые контроллеры представления, и вы, как правило, никогда не должны игнорировать большинство предупреждений, кроме, возможно, соглашений кода.
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) strongSelf = weakSelf;
strongSelf->myClassesIVar --;
});