Deinit pas appelé sur un UIViewController, mais Dealloc est
Il semble que le Swift équivalent de dealloc
deinit
. Toutefois, lorsque vous tentez de définir la méthode sur un UIViewController, il ne se comporte pas comme vous le souhaiteriez...
Installation
- Créer une nouvelle Vue Unique du projet à l'aide de Xcode 7.0, soit Swift ou Objective-C.
- Ajouter un "rejeter" sur le bouton de vue-contrôleur qui a été créé avec le storyboard (je vais reporter ce point de vue, le contrôleur de VC2; sa classe est ViewController).
- Ajouter une nouvelle vue-contrôleur et mis à la vue initiale de contrôleur (VC1, la classe est nul).
- Ajouter un "cadeau" pour VC1 avec un "cadeau Modal" segue à VC2.
- Dans VC2 code, à mettre un point d'arrêt dans
deinit
(Swift) oudealloc
(Objective-C). - Dans VC2, faire "disparaître" le bouton de action du procédez de la manière suivante:
//Swift: presentingViewController?.dismissViewControllerAnimated(true, completion: nil) //Objective-C: [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
- Exécuter l'application et appuyez sur les deux boutons pour présenter VC2 et puis la rejeter.
Remarquez comment dans Objective-C, la dealloc
point d'arrêt est atteint.
Dans Swift, d'autre part, la deinit
point d'arrêt n'est jamais atteint.
Pourquoi est deinit
jamais appelé? Est-ce un bug ou pas?
Si c'est par la conception, où dois-je nettoyer le code de libérer des ressources lorsque le contrôleur ne sera plus nécessaire? (Il ne peut pas être dans viewDidUnload
depuis cette méthode est obsolète. Il ne peut pas être dans viewDidDisappear
parce que quelque chose d'autre pourrait être la tenue d'une référence à elle et finira par se montrer à nouveau.)
Remarque: Si vous tentez de définir une dealloc
méthode rapide, vous obtenez l'erreur suivante:
Méthode dealloc()' avec Objective-C sélecteur 'dealloc conflits avec deinitializer avec le même Objectif-C sélecteur.
Si vous avez le point de vue de Swift contrôleur hérite de l'Objective-C contrôleur, et vous mettez un point d'arrêt dans l'Objective-C dealloc méthode, vous obtiendrez le même buggy comportement défini ci-dessus: le deinit
ne sera pas appelé, mais le dealloc
sera appelée.
Si vous tentez d'utiliser les Allocations pour afficher le nombre d'instances de la classe dans la mémoire, les deux versions montrent la même chose: La # Persistent
est toujours 1, et la # Transient
augmente à chaque fois que vous vous montrez le second point de vue du contrôleur.
Compte tenu de la configuration ci-dessus, il ne devrait pas être forte de cycle de référence tenant à la vue-contrôleur.
OriginalL'auteur Senseful | 2015-10-13
Vous devez vous connecter pour publier un commentaire.
TLDR:
Les points d'arrêt ne fonctionnent que dans
deinit
si il y a un exécutable ligne de code à l'avance.deinit
méthode.Grâce à Adam pour me pointer dans la bonne direction. Je n'ai pas fait des 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 travaillent (par exemple, mettre en pause l'exécution ou à effectuer leur action comme l'enregistrement d'un message) sera indiqué par l' ➤ symbole.
Normalement les points d'arrêt sont touchés de façon libérale, même si une méthode ne fait rien:
Cependant, dans un vide
deinit
méthode, PAS points d'arrêt sera jamais à obtenir frappé:En ajoutant plus de lignes de code, nous pouvons voir que ça dépend si il y a un exécutable ligne de code après le point d'arrêt:
En particulier, jouent attention aux lignes 7 et 8, car cela diffère de manière significative de la façon dont
doNothing()
comportés!Si vous vous êtes habitué à ce comportement de la façon dont le point d'arrêt sur la ligne 4 a travaillé dans
doNothing()
, vous pouvez mal en déduire 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 cet exemple:Remarque: pour les points d'arrêt qui permet de suspendre l'exécution sur la même ligne, ils sont frappés dans l'ordre dans lequel ils ont été créés. Pour tester leur ordre, j'ai mis un point d'arrêt à Message de Journal et continuer Automatiquement après évaluation des actions.
Remarque: lors De mes tests, il y avait aussi un autre écueil potentiel qui peut vous: Si vous utilisez
print("test")
, il apparaîtra le Débogage de la Zone pour vous montrer le message (le message s'affiche en gras). Toutefois, si vous ajoutez un point d'arrêt et le dire à Message de Journal, il va enregistrer dans un texte ordinaire et pas pop ouvrir le Débogage de la Zone. Vous devez ouvrir manuellement le Débogage de la Zone pour voir le résultat.Note: Ceci a été testé tous dans Xcode 7.1.1
Êtes-vous sûr que votre vue-contrôleur est en train d'être libéré?
Je vous remercie. Cela avait foutu la moitié de ma journée.
OriginalL'auteur Senseful
Je n'ai pas encore essayé, mais je n'ai trouver cette pour vous:
Il semble que la fonction ne sera pas appelé, sauf si un code est mis à l'intérieur de la deinit (bizarre) doivent faire partie de swift étape d'optimisation.
Essayer de mettre une instruction d'impression à l'intérieur de votre deinit comme l'a suggéré et vos constatations
Merci de voir stackoverflow.com/a/33788952/35690 pour une explication plus complète!
OriginalL'auteur Adam Campbell