Nettoyer la façon de forcer la vue à charger les sous-vues au début

Récemment, j'ai écrit du code où j'ai essayé de faire reference à une sortie sur un UIViewController que j'avais juste instanciée avec [storyboard instantiateViewControllerWithIdentifier] et de modifier la sous-vue pointée vers la sortie avant de présenter le ViewController . Cela n'a pas fonctionné parce que la vue de ViewController n'avait pas encore chargé ses sous-vues, y compris celle à laquelle mon sharepoint vente faisait reference, donc la propriété m'a juste donné un pointeur nul.

Après (avec un peu de difficulté) pour find la cause de mon problème dans le débogueur, j'ai parcouru Google et appris, grâce à des réponses comme celle-ci , que je pouvais charger la vue sans charger le viewer myViewController.view . Après cela, je peux accéder à mon sharepoint vente sans aucun problème.

C'est un hack clair, cependant, et Xcode – à juste titre – ne l'aime pas, et proteste avec colère avec cet avertissement:

Résultat d'access à la propriété inutilisé – les getters ne doivent pas être utilisés pour les effets secondaires

Existe-t-il une autre façon non-hacky de faire cela qui n'implique pas abuser du getter .view ? Sinon, existe-t-il des templates canoniques / idiomatiques pour ce scénario impliquant quelque chose comme l'ajout dynamic d'un gestionnaire à appeler dès que les sous-vues sont chargées?

Ou est la solution standard juste pour replace myViewController.view avec [myViewController view] pour fermer l'avertissement de Xcode, puis vivre avec le hack?

Sur iOS 9 ou plus récent, on peut utiliser:

 viewController.loadViewIfNeeded() 

Docs: https://developer.apple.com/reference/uikit/uiviewcontroller/1621446-loadviewifneeded

Je suis d'accord que forcer une vue à charger devrait être évité mais j'ai couru dans un cas où il a semblé la seule solution raisonnable à un problème (sauter UINavigationController contenant un UISearchController qui devait encore être invoqué provoque une console désagréable dit avertissement).

Ce que j'ai fait était d'utiliser la nouvelle API iOS9 loadViewIfNeeded et pour pre-iOS9 utilisé viewController.view.alpha = 1.0. Bien sûr, un bon commentaire au-dessus de ce code vous empêchera (ou quelqu'un d'autre) de supprimer ce code plus tard en pensant qu'il n'est pas nécessaire.

Le fait qu'Apple fournisse maintenant cette API signale qu'elle peut être nécessaire de time en time.

fusionné Rudolph / Swany réponses pour les objectives de deployment pre ios9

  if #available(iOS 9.0, *) { loadViewIfNeeded() } else { // _ = self.view works but some Swift comstackr genius could optimize what seems like a noop out // hence this perversion from this recipe http://stackoverflow.com/questions/17279604/clean-way-to-force-view-to-load-subviews-early view.alpha = 1 } 

Si je vous comprends bien, je pense qu'il existe une autre solution assez standard: déplacer le code de modification / configuration de sortie dans une méthode viewDidLoad (du VC récemment instancié).

Le sujet est également discuté dans cette question .

Cela nécessiterait une certaine restructuration, mais cela pourrait vous donner une design plus «propre» en termes de MVC si votre VC entrant gérait sa propre configuration, et éviterait la ressortingction «Vous ne devriez jamais appeler cette méthode directement» sur loadView .

Vous pouvez appeler [myViewController loadView] pour charger explicitement la vue, au lieu d'abuser du getter .view . Le .view loadView appelle réellement loadView si nécessaire lorsqu'il est appelé.

Ce n'est toujours pas une très bonne solution, car la section de la documentation de loadView sur loadView explicitement que

Vous ne devriez jamais appeler cette méthode directement