2017-06-13 2 views
2

En général, je suis conscient que nous n'avons pas besoin de nous affaiblir lorsque nous utilisons UIView.animate() parce que le bloc n'est pas maintenu mais il y a un argument pour utiliser weak dans le bit de code suivant ? Pourquoi quelqu'un dirait qu'il pourrait y avoir?Devrait être faible dans UIView.animate lorsqu'il y a un délai et dans la vue de collection effectuer des mises à jour par lots?

UIView.animate(withDuration: 0.1, animations: { 
    self.performAction() 
} 

Dans l'exemple suivant pourquoi avons-nous besoin d'utiliser self faible/pas besoin d'utiliser self faible ...?

collectionView.performBatchUpdates({ 
    self.collectionView.reloadData() 
    ... 
}) 

Répondre

2

Contexte:

blocs/fermetures sont rien de plus que des objets de référence compté dans la mémoire Heap. Lorsque vous créez un bloc et maintenez la forte référence au bloc/fermeture, vous déclarez que le nombre de références du bloc est incrémenté de 1.

Cela signifie évidemment que le bloc ne sera pas libéré même après son exécution depuis la mémoire, jusqu'à ce que Les classes qui tiennent fermement la référence au bloc libèrent leur forte emprise. Maintenant, gardez cela à l'esprit, si vous passez un self fort à bloquer, car les variables utilisées dans le bloc sont maintenues en vie jusqu'à ce que le bloc termine son exécution (Context capture qui est la principale différence entre la fonction et les blocs). ne pas être libéré avant que le bloc lui-même ne soit libéré. Maintenant c'est un deadLock :) Votre auto contient une forte référence à l'objet bloc et l'objet bloc interne contient la forte référence à soi. Maintenant, les deux vont attendre que l'autre se relâche et finissent par ne jamais se relâcher.

Réponse à votre question:

Comme vous l'avez si vous ne tenez pas fortement la référence du bloc UIView.animate, il n'y a aucune raison impérieuse pour vous de passer l'auto faible est donc le cas pour CollectionView mise à jour par lots.

Dans votre cas

collectionView.performBatchUpdates({ 
    self.collection.reloadData() 
    ... 
}) 

je crois que la collection est CollectionView, si c'est un IBOutlet vous devez avoir observé que son été déclarée comme objet faible. Donc, votre code doit avoir l'air plus comme

collectionView.performBatchUpdates({ 
    self.collection?.reloadData() 
    ... 
}) 

Hope it helps

+0

Merci pour votre réponse. Je suppose que ma question est maintenant pourquoi quelqu'un dirait que le soi ne devrait pas être capturé fortement dans ces situations? Y at-il une situation où le délai/mise à jour est un moment, l'utilisateur va ailleurs, le parent (c'est-à-dire le contrôleur) est désalloué et que se passe-t-il? Ou est-ce mal de dire que le soi devrait être faible? – jeh

+0

Si self est passé à un bloc, self ne sera pas désaffecté même si l'utilisateur s'éloigne comme si l'on appuyait sur le bouton back et que l'on se déplaçait vers le VC parent. Vous pouvez vérifier ceci en écrivant deinit. Seulement après l'achèvement du bloc deinit sera appelé. Alors maintenant vous savez ce qui se passe si l'utilisateur s'éloigne :) self ne sera pas nul s'il est fortement capturé. Mais les composants de l'interface utilisateur glissés comme IBOutlet sont faibles par défaut. Ainsi, au moment où votre bloc accède à ces composants, ils peuvent avoir été libérés parce que, par définition, ils n'ont jamais été maintenus fermement –

+0

D'un autre côté, tout ce qui est fortement retenu par soi sera disponible à l'intérieur du bloc. C'est pourquoi j'ai ajouté cet extrait où j'accédais à la vue de collection en utilisant? Et ne pas utiliser!:) Enfin, parce que self ne sera pas libéré jusqu'à la fin du blocage, le seul autre scénario où je passerais un moi faible serait si mon exécution de bloc prend une éternité ou si j'ai un bloc facultatif que je n'exécuterais jamais selon certaines conditions. Dans de tels scénarios se passer soi-même serait suicidaire :) –