Il ressemble à Swift équivalent de dealloc
est deinit
. Cependant, lorsque vous essayez de définir la méthode sur un UIViewController, il ne se comporte pas comme prévu ...
Configuration
deinit
(Swift) ou dealloc
(Objective-C).Dans VC2, effectuez l'action du bouton "ignorer" comme suit:
// Swift:
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
// Objective-C:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Remarquez comment dans Objective-C , le point d'arrêt dealloc
est atteint .
Dans Swift , d'autre part, le point d'arrêt deinit
n'est jamais atteint .
Pourquoi deinit
n'est-il jamais appelé? Est-ce un bug ou par conception?
Si c'est de par leur conception, où dois-je mettre du code de nettoyage pour libérer des ressources lorsque le contrôleur de vue ne sera plus nécessaire? (Elle ne peut pas être dans viewDidUnload
car cette méthode est obsolète. Elle ne peut pas être dans viewDidDisappear
parce que quelque chose d'autre pourrait contenir une référence et l'affichera éventuellement à nouveau.)
Remarque: Si vous essayez de définir une méthode dealloc
dans Swift, vous obtenez l'erreur suivante:
La méthode 'dealloc ()' avec le sélecteur Objective-C 'dealloc' entre en conflit avec le déinitialiseur avec le même sélecteur Objective-C.
Si vous avez le contrôleur de vue Swift hérité d'un contrôleur Objective-C, et que vous placez un point d'arrêt dans la méthode dealloc Objective-C, vous obtiendrez le même comportement de bogue défini ci-dessus: le deinit
ne sera pas appelé, mais le dealloc
sera appelé.
Si vous essayez d'utiliser des allocations pour afficher le nombre d'instances de la classe en mémoire, les deux versions affichent la même chose: le # Persistent
est toujours 1 et le # Transient
augmente chaque fois que vous affichez le deuxième contrôleur de vue.
Compte tenu de la configuration ci-dessus, il ne devrait pas y avoir cycle de référence fort accroché au contrôleur de vue.
TLDR:
deinit
que s'il y a une ligne de code exécutable devant eux.deinit
.Merci à Adam de m'avoir pointé dans la bonne direction . Je n'ai pas fait de tests approfondis, mais il semble que les points d'arrêt se comportent différemment dans deinit
que partout ailleurs dans votre code.
Je vais vous montrer plusieurs exemples où j'ai ajouté un point d'arrêt sur chaque numéro de ligne. Ceux qui fonctionneront (par exemple, interrompre l'exécution ou effectuer leur action, comme enregistrer un message) seront indiqués via le symbole ➤.
Normalement, les points d'arrêt sont généreusement atteints, même si une méthode ne fait rien:
➤ 1
➤ 2 func doNothing() {
➤ 3
➤ 4 }
5
Cependant, dans une méthode deinit
vide, [~ # ~] aucun [~ # ~] point d'arrêt ne sera jamais atteint:
1
2 deinit {
3
4 }
5
En ajoutant plus de lignes de code, nous pouvons voir que cela dépend si une ligne de code exécutable suit le point d'arrêt:
➤ 1
➤ 2 deinit {
➤ 3 //
➤ 4 doNothing()
➤ 5 //
➤ 6 foo = "abc"
7 //
8 }
9
En particulier, portez une attention particulière aux lignes 7 et 8, car cela diffère considérablement de la façon dont doNothing()
s'est comporté!
Si vous vous êtes habitué à ce comportement du fonctionnement du point d'arrêt sur la ligne 4 dans doNothing()
, vous pouvez déduire à tort que votre code ne s'exécute pas si vous n'aviez qu'un point d'arrêt sur la ligne 5 (ou même 4) dans ce exemple:
➤ 1
➤ 2 deinit {
➤ 3 number++
4 // incrementNumber()
5 }
6
Remarque: pour les points d'arrêt qui interrompent l'exécution sur la même ligne, ils sont affichés dans l'ordre de leur création. Pour tester leur commande, j'ai défini un point d'arrêt sur Message de journal et Continuer automatiquement après avoir évalué les actions.
Remarque: Lors de mes tests, il y avait également un autre piège potentiel qui pourrait vous amener: Si vous utilisez print("test")
, il apparaîtra dans la zone de débogage pour vous montrer le message (le message apparaît en gras). Cependant, si vous ajoutez un point d'arrêt et que vous le dites à Consigner le message , il le consignera en texte normal et pas ouvrez la zone de débogage. Vous devez ouvrir manuellement la zone de débogage pour voir la sortie.
Remarque: Tout cela a été testé dans Xcode 7.1.1
Je ne l'ai pas encore essayé mais j'ai trouvé this pour vous:
Il semble que la fonction ne sera pas appelée à moins qu'un code ne soit placé à l'intérieur du deinit (bizarre) doit faire partie de l'étape d'optimisation de Swift.
Essayez de mettre une déclaration imprimée à l'intérieur de votre deinit comme suggéré et signalez vos résultats