Compte tenu des éléments suivants:
- (void) someMethod
{
dispatch_async(dispatch_get_main_queue(), ^{
myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
target: self
selector: @selector(doSomething)
userInfo: nil
repeats: NO];
});
}
Où myTimer est déclaré dans une interface privée:
@interface MyClass()
{
NSTimer * myTimer;
}
@end
Comment corriger l'avertissement suivant:
Block conserve implicitement "soi"; mentionner explicitement "soi" pour indiquer qu'il s'agit d'un comportement voulu
D'après ce que j'ai trouvé jusqu'à présent, la plupart des suggestions impliquent de mettre quelque chose comme:
- (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];
});
}
Sauf que myTimer est un ivar, ce qui signifie que wself
n'a accès à aucune propriété.
Je suppose que mes questions sont:
J'utilise beaucoup d'ivars via mon code. Je viens d'ajouter le -Weverything
signaler à mon projet pour voir si je peux trouver des problèmes sous-jacents et c'est de loin l'avertissement le plus courant. Je n'ai aucun problème à le faire et à le réparer en faisant mes propriétés d'ivars, mais je veux m'assurer d'avoir une meilleure compréhension avant de le faire.
Remplacement de myTimer
par self->myTimer
résoudrait votre avertissement.
Lorsque vous utilisez un iVar _iVar
dans le code, le compilateur remplacera le code par self->_iVar
, et si vous l'utilisez dans un bloc, le bloc se capturera lui-même au lieu de l'iVar lui-même. L'avertissement est juste pour s'assurer que le développeur comprend ce comportement.
Xcode: 9.2, 10.2
J'ai un projet Swift. Avertissement Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
apparaît lorsque j'utilise des modules Objective-C:
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO
Ajoutez à la fin de votre 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
Pour ceux d'entre vous qui reçoivent ces avertissements en raison de Bolts
/FBSDKCoreKit
/FBSDKLoginKit
, vous devez éviter la réponse de Vasily et au lieu de cela, mettre en garde les avertissements pour ces dépendances spécifiques.
Mentionnez chaque module au lieu de simplement FacebookCore et ajoutez inhibit_warnings: true
pod 'FacebookCore', inhibit_warnings: true
pod 'Bolts', inhibit_warnings: true
pod 'FBSDKCoreKit', inhibit_warnings: true
pod 'FBSDKLoginKit', inhibit_warnings: true
Ou désactivez tous les pods en ajoutant à votre podfile ceci:
inhibit_all_warnings!
Vous recevrez toujours des avertissements pour votre propre code. Ne pas les obtenir pourrait être problématique à un moment donné, c'est pourquoi je pense que c'est une meilleure solution.
La prochaine fois que vous mettrez à jour le SDK Facebook, voyez si vous pouvez supprimer le inhibit_warnings: true
ou inhibit_all_warnings!
.
Cela résout mon problème pour 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];
}
});
}
Récemment, j'ai rencontré le même problème et la réponse @Vasily Bodnarchuk semble être utile.
Cependant, dans les environnements d'intégration continue, il n'est pas possible de changer l'indicateur CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
En NO
au moment de l'exécution. Donc, afin d'isoler le problème, j'ai essayé en vérifiant tous les GEMS dépendants installés par Cocoapods et j'ai compris que la gemme XCODEPROJ version 1.5.7 définit le CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
Sur YES
chaque fois que pod install
la commande est exécutée. La solution à cela est de XCODEPROJ à la version antérieure 1.5.1 en exécutant Sudo gem install xcodeproj -v 1.5.1
Une fois rétabli, exécutez simplement pod install
et l'indicateur sera toujours défini sur NO.