viewDidLoad appelé deux fois sur rootViewController au lancement
Ce que quelqu'un sait pourquoi cette racine View Controller's
viewDidLoad
est appelé deux fois au lancement? Ça me rend fou!
voici la trace de la pile à partir de la première fois par le biais de viewDidLoad
:
#0 0x0000276a in -[RootViewController viewDidLoad] at RootViewController.m:71
#1 0x3097548f in -[UIViewController view]
#2 0x00002734 in -[RootViewController initWithCoder:] at RootViewController.m:39
#3 0x30ab5ce4 in -[UIClassSwapper initWithCoder:]
#4 0x30514636 in _decodeObjectBinary
#5 0x30514035 in _decodeObject
#6 0x30ab5a1d in -[UIRuntimeConnection initWithCoder:]
#7 0x30514636 in _decodeObjectBinary
#8 0x30515f27 in -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
#9 0x305163b0 in -[NSArray(NSArray) initWithCoder:]
#10 0x30514636 in _decodeObjectBinary
#11 0x30514035 in _decodeObject
#12 0x30ab4dde in -[UINib instantiateWithOptions:owner:loadingResourcesFromBundle:]
#13 0x30ab6eb3 in -[NSBundle(NSBundleAdditions) loadNibNamed:owner:options:]
#14 0x308f85f1 in -[UIApplication _loadMainNibFile]
#15 0x30901a15 in -[UIApplication _runWithURL:sourceBundleID:]
#16 0x308fef33 in -[UIApplication handleEvent:withNewEvent:]
#17 0x308fad82 in -[UIApplication sendEvent:]
#18 0x309013e1 in _UIApplicationHandleEvent
#19 0x32046375 in PurpleEventCallback
#20 0x30245560 in CFRunLoopRunSpecific
#21 0x30244628 in CFRunLoopRunInMode
#22 0x308f930d in -[UIApplication _run]
#23 0x309021ee in UIApplicationMain
#24 0x000022e4 in main at main.m:14
et la deuxième fois:
#0 0x0000276a in -[RootViewController viewDidLoad] at RootViewController.m:71
#1 0x30ab50cd in -[UINib instantiateWithOptions:owner:loadingResourcesFromBundle:]
#2 0x30ab6eb3 in -[NSBundle(NSBundleAdditions) loadNibNamed:owner:options:]
#3 0x308f85f1 in -[UIApplication _loadMainNibFile]
#4 0x30901a15 in -[UIApplication _runWithURL:sourceBundleID:]
#5 0x308fef33 in -[UIApplication handleEvent:withNewEvent:]
#6 0x308fad82 in -[UIApplication sendEvent:]
#7 0x309013e1 in _UIApplicationHandleEvent
#8 0x32046375 in PurpleEventCallback
#9 0x30245560 in CFRunLoopRunSpecific
#10 0x30244628 in CFRunLoopRunInMode
#11 0x308f930d in -[UIApplication _run]
#12 0x309021ee in UIApplicationMain
#13 0x000022e4 in main at main.m:14
Vous devez vous connecter pour publier un commentaire.
Bizarre. Je n'ai pas vu ce cas particulier, mais en général, vous devriez supposer que viewDidLoad peut être appelée plusieurs fois. Il va avoir appelé à chaque fois qu'une plume fichier qui fait référence à ce contrôleur est chargé.
Pour une application simple avec une seule plume, qui ne devrait pas arriver. Mais en plus complexes d'une application qui permet de charger et de décharger les contrôleurs de vue, cela arrive tout le temps.
viewDidUnload
est obsolète. Apple docs: "points de Vue ne sont plus purgés sous une faible mémoire et donc cette méthode n'est jamais appelée.". developer.apple.com/documentation/uikit/uiviewcontroller/... DoncviewDidLoad
sera généralement seulement être appelé qu'une seule fois dans la vie d'une-vue-contrôleur.J'ai eu ce même problème lors de mon app a été le premier lancement. Ce que j'ai trouvé était que dans ma MainWindow.xib fichier, j'ai été paramètre à la fois mon Application Délégué
viewController
prise de courant, et ma Fenêtre estrootViewController
prise de vue de la racine de mon contrôleur. Lorsque vous créez une Vue de fichier projet dans Xcode, votre Délégué d'Application dudidFinishLaunchingWithOptions
seront pré-remplis avec:Je crois que le
self.viewController
ivar est instancié à partir d'MainWindow.xib avantdidFinishLaunchingWithOptions
est appelée. Puis la pré-rempli de code ci-dessus définit la FenêtrerootViewController
. Donc, si, en parallèle, vous spécifiez lerootViewController
prise de la Fenêtre de votre MainWindow.xib fichier, votre vue de la racine contrôleur sera effectivement créé deux fois et a ajouté que la Fenêtre de la vue racine contrôleur à deux reprises.pre
J'ai fait un peu de débogage, et voici ce que j'ai trouvé sur le
ViewController
ordre de chargement:Au cours de la méthode loadView,
initWithCoder:
est appelé, et une nouvelle copie de laviewController
est créé. c'est ce qui est passé dans un certain nombre de méthodes (commeviewDidLoad
). la copie est détruite plus tard dans un dealloc appel. la bonne nouvelle, c'est que, dans cet exemplaire, conservé points de vente ne sont pas configurés, de sorte que vous pouvez l'utiliser comme un test pour savoir si vous devez les initialiser les variables, appeler d'autres méthodes, et plus important encore, si vous devez libérer et de détruire des objets lors de dealloc.Emporter clé: le réel
viewController
aura sa conservéIBOutlet
propriétés configurées. si vous êtes dans une méthode de remplacement qui est appelée plusieurs fois, il suffit de consulter l'un de vos conservéIBOutlet
propriétés pourNULL
. si ils sontNULL
, puis retourner immédiatement.Quelqu'un a obtenu des indices quant à pourquoi cela se passe de cette façon?
Effet secondaire de ceci: vous ne pouvez pas utiliser
awakeFromNib
de manière fiable.Vous ne pouvez pas assumer viewDidLoad sera appelée qu'une seule fois. Si vous êtes l'initialisation d'objets et que vous voulez une garantie effectuer l'initialisation soit dans la méthode init ou si vous êtes chargement à partir d'un fichier nib de la awakeFromNib méthode.
J'ai eu un problème similaire et c'était un résultat de renommer mon fichier XIB et ses
ViewController
classe (Propriétaire du Fichier). Ne pas le faire, comme il a vraiment eu de la vue et des délégués misdefined à l'intérieur de l'XML et il n'était pas récupérable. Pendant ce temps, j'ai eu une référence à la charge de la VC original qui était censé être mon nouveau VC. Je crois qui a causé la mère de recréer lui-même, puis le CR j'ai été vraiment essayé de l'appeler. En gros, j'ai créé un la récursivité indirecte de la CR qui a x2viewDidLoad
entrées dans ma trace.Je ne pense pas qu'il n'y a aucune raison valable pour x2
viewDidLoad
que c'est une genèse, et peuvent invoquer d'autres initialisation avec le mauvais suppose des pré-conditions. Chaque fois que j'ai vu le x2 viewDidLoad, c'était une erreur de codage de ma part, très souvent quand j'étais refactoring et le déplacement de VC classes autour de.Si il y a une raison valable de plus que sur
viewDidLoad
appel, veuillez quelqu'un (Dev Apple êtes-vous à l'écoute de l'expliquer en détail technique -- j'ai été à la recherche pour cette réponse depuis des mois maintenant.J'ai eu ce problème, mais a été en mesure de le réparer.
Solution:
Renommer le point de vue de la classe contrôleur qui se charge deux fois.
Détails:
De le renommer et de le rendre le nouveau nom de quelque chose d'entièrement nouveau. De renommer le fichier ne s'arrête pas à la charge deux fois question. La création d'un nouveau projet (comme suggéré par d'autres), peut-être exagéré, essayons au moins de la plus simple des solutions de premier! Renommez la classe de la destination VC.
Soupçon:
Si un changement de nom de la classe résout votre problème, vous alors évidemment devez mettre à jour tous vos références à cette catégorie. Vous pouvez accélérer le processus en utilisant la Commande+Maj+F pour le projet à l'échelle de trouver.
J'ai rencontré le même problème que j'ai été la refonte d'un
ViewController
à partir de zéro pour se débarrasser de la XIB fichier et de faire la classe réutilisable. J'ai eu ce deuxièmeViewController
instance qui devrait recevoir uneviewDidLoad
message suivie par un dealloc message.J'ai trouvé que c'était le résultat de la
loadView
méthode qui n'est pas en train d'être redéfini dans leViewController
. La valeur par défautloadView
appeléawakeFromNib
, avec lanibName
propriété est définie sur le nom de la classe. Même si j'avais supprimé le fichier XIB de ce projet, il était encore dans le répertoire de l'application sur le simulateur.Donc, même si vous pourriez juste réinitialiser le contenu et les paramètres du simulateur pour se débarrasser de la deuxième
viewDidLoad
, une meilleure façon peut-être à juste redéfinirloadView
comme ceci:Il fait sens si l'on considère la documentation de la
UIViewController's
vue de la propriété:Dans mon cas, je n'ai pas remarqué ce que j'ai réellement affecté la rootViewController deux fois:
application:didFinishLaunchingWithOptions:
etapplicationDidBecomeActive:
Juste pour ajouter à cela, si vous utilisez un système de fonction, tels que TouchID, puis applicationWillResignActive dans votre AppDelegate se invoquée, et si vous la dire, la réinitialisation de contrôleurs de Sécuriser la Racine Contrôleur, puis vous obtenez reinvoked, et performSegueWithIdentifier(de soi.MAIN_SEGUE ,de l'expéditeur: auto) ne sera pas le feu!
Ce qui m'est arrivé lorsque j'ai fusionné un projet à partir de la maquette à l'ancienne à l'aide de xibs pour la construction de points de vue. La raison principale pour la commutation de retour était le fait que je ne pouvais pas correctement mis en place un modal s'afficher correctement. La façon dont j'ai l'habitude de le faire, c'est d'avoir un délégué de la méthode à partir d'un UIButton construire une instance d'un certain viewcontroller, définir certaines de ses propriétés (le plus important étant le délégué afin que je puisse bien rejeter le modèle vue contrôleur) et ensuite le présenter de manière modale. Dans le nouveau storyboard façon, c'est soi-disant fait avec un segue. La personnalisation de la transition n'est faisable que par une classe personnalisée qui s'étend de la UIStoryboardSegue classe. Je trouve cela beaucoup trop de tracas par rapport à la simple façon dont il utilisé pour être si je fusionnées.
Comment cette cause de moi pour avoir un viewcontroller charge deux fois? Lors du transfert du code du storyboard projet à la xib projet, j'ai fait une couple de xibs (un pour chaque ViewController) et copié le viewcontroller objet à partir de la table de montage séquentiel. Cela a conduit à une xib en elle pas un viw, mais un viewcontroller; sens j'avais mis un viewcontroller dans un viewcontroller (puisque le propriétaire du fichier est également une instance de la viewcontroller). Je ne pense pas que dans votre cas, que vous avez eu ce problème mais j'espère que ça peut-être aider quelqu'un un jour.
Pour résoudre ce déplacement de la vue à partir de l'affichage de contrôleur de la vue-contrôleur et au niveau de la racine de la section objets. Fois le point de vue du contrôleur et de navigation de l'article devrait être supprimé. Construire et exécuter et vous devriez voir une seule allocation pour la vue-contrôleur. C'est le propriétaire du fichier.