Comment puis-je éviter cet avertissement dans xcode. Voici l'extrait de code:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
user1845209
la source
la source
timerDisp
propriété est-elle sur la classe?player(AVPlayer object)
ettimerDisp(UILabel)
?Réponses:
La capture d'
self
ici arrive avec votre accès implicite à la propriété deself.timerDisp
- vous ne pouvez pas faire référence àself
ou à des propriétésself
dans un bloc qui sera fortement conservé parself
.Vous pouvez contourner cela en créant une référence faible
self
avant d'accéder à l'timerDisp
intérieur de votre bloc:la source
__unsafe_unretained
place.self
, il est conservé par la file d'attente principale de répartition. Ai-je tort?Et une chose très importante à retenir: n'utilisez pas de variables d'instance directement dans le bloc, utilisez-les comme propriétés d'un objet faible, échantillon:
et n'oubliez pas de faire:
un autre problème peut apparaître si vous passez une copie faible de l'objet non conservé par quelqu'un:
Si
vcToGo
sera désalloué et que ce bloc sera déclenché, je pense que vous obtiendrez un crash avec un sélecteur non reconnu dans une corbeille qui contientvcToGo_
maintenant une variable. Essayez de le contrôler.la source
Meilleure version
Donc, le tout serait comme ça:
J'ai lu cet article plusieurs fois. Ceci est un excellent article par Erica Sadun sur la façon d'éviter les problèmes lors de l'utilisation de blocs et de NSNotificationCenter
Mise à jour rapide:
Par exemple, dans swift, une méthode simple avec bloc de réussite serait:
Lorsque nous appelons cette méthode et devons l'utiliser
self
dans le bloc de réussite. Nous utiliserons les fonctionnalités[weak self]
etguard let
.Cette danse dite forte-faible est utilisée par des projets open source populaires
Alamofire
.Pour plus d'informations, consultez le guide de style rapide
la source
typeof(self) strongSelf = self;
dehors du bloc (au lieu de __weak) puis dans le bloc ditstrongSelf = nil;
après utilisation? Je ne vois pas comment votre exemple garantit que faiblesseSelf n'est pas nul au moment où le bloc s'exécute.Dans une autre réponse, Tim a déclaré:
Ce n'est pas tout à fait vrai. Vous pouvez le faire tant que vous rompez le cycle à un moment donné. Par exemple, disons que vous avez une minuterie qui se déclenche qui a un bloc qui se conserve et que vous gardez également une référence forte à la minuterie en soi. C'est parfaitement bien si vous savez toujours que vous allez détruire la minuterie à un moment donné et briser le cycle.
Dans mon cas tout à l'heure, j'ai eu cet avertissement pour le code qui:
Maintenant, je sais que clang ne produira cet avertissement que s'il détecte que la méthode commence par «set» (et un autre cas spécial que je ne mentionnerai pas ici). Pour moi, je sais qu'il n'y a aucun danger qu'il y ait une boucle de retenue, j'ai donc changé le nom de la méthode en «useY:» Bien sûr, cela pourrait ne pas être approprié dans tous les cas et généralement vous voudrez utiliser une référence faible, mais J'ai pensé qu'il valait la peine de noter ma solution au cas où cela aiderait les autres.
la source
Plusieurs fois, ce n'est pas réellement un cycle de conservation .
Si vous savez que ce n'est pas le cas, vous n'avez pas besoin de mettre au monde des faibles faibles.
Apple nous impose même ces avertissements avec l'API
UIPageViewController
, ce qui inclut une méthode définie (qui déclenche ces avertissements - comme mentionné ailleurs - en pensant que vous définissez une valeur pour un ivar qui est un bloc) et un bloc de gestionnaire d'achèvement (dans lequel vous vous référerez sans aucun doute à vous-même).Voici quelques directives du compilateur pour supprimer l'avertissement de cette seule ligne de code:
la source
Ajout de deux cents sur l'amélioration de la précision et du style. Dans la plupart des cas, vous n'utiliserez qu'un ou deux membres de
self
dans ce bloc, très probablement juste pour mettre à jour un curseur. Le castingself
est exagéré. Au lieu de cela, il vaut mieux être explicite et ne diffuser que les objets dont vous avez vraiment besoin à l'intérieur du bloc. Par exemple, si c'est une instance deUISlider*
, disons,_timeSlider
faites simplement ce qui suit avant la déclaration de bloc:Ensuite, utilisez simplement l'
slider
intérieur du bloc. Techniquement, cela est plus précis car il réduit le cycle de rétention potentiel à l'objet dont vous avez besoin, pas à tous les objets à l'intérieurself
.Exemple complet:
De plus, très probablement, l'objet projeté sur un pointeur faible est déjà un pointeur faible à l'intérieur, ce
self
qui minimise ou élimine complètement la probabilité d'un cycle de rétention. Dans l'exemple ci-dessus,_timeSlider
est en fait une propriété stockée en tant que référence faible, par exemple:En termes de style de codage, comme avec C et C ++, les déclarations de variables sont mieux lues de droite à gauche. Déclarant
SomeType* __weak variable
dans cet ordre se lit plus naturellement de droite à gauche comme:variable is a weak pointer to SomeType
.la source
J'ai rencontré cet avertissement récemment et je voulais mieux le comprendre. Après un peu d'essais et d'erreurs, j'ai découvert qu'elle provenait du fait qu'une méthode commence par "ajouter" ou "enregistrer". Objective C traite les noms de méthode commençant par "new", "alloc", etc. comme renvoyant un objet conservé mais ne mentionne (que je peux trouver) rien concernant "add" ou "save". Cependant, si j'utilise un nom de méthode de cette manière:
Je verrai l'avertissement sur la ligne [self done]. Cependant, cela ne:
Je vais aller de l'avant et utiliser la méthode "__weak __typeof (self) faiblesseSelf = self" pour référencer mon objet mais n'aime vraiment pas avoir à le faire car cela confondra un futur moi et / ou un autre développeur. Bien sûr, je ne pouvais pas non plus utiliser "ajouter" (ou "enregistrer") mais c'est pire car cela enlève le sens de la méthode.
la source