Conteneur UIViewController Pas de le Libérer de l'Enfant de voir les Contrôleurs
J'ai un conteneur personnalisé UIViewController qui a six enfants UIViewControllers, et un ensemble d'onglets que l'utilisateur interagit avec pour basculer entre la vue enfant contrôleurs. Le problème, c'est quand mon conteneur de-vue-contrôleur est relâché, l'enfant de voir les contrôleurs ne sont pas.
J'ai vérifié que l'enfant de voir les contrôleurs ne sont pas libérés par l'ajout d'un peu de débogage de code à leur dealloc méthodes, et ils sont remis en liberté tant que leur vue ne sont pas ajoutés au conteneur affichage du contrôleur de vue.
Ci-dessous est un extrait du code que j'utilise pour créer mes conteneur personnalisé-vue-contrôleur. Le viewController les pointeurs sont iVars. Je suis également à l'aide de l'ARC de sorte que c'est pourquoi il n'y a pas de version d'appels.
- (void)init
{
if ((self = [super init])) {
vc1 = [[UIViewController alloc] init];
[self addChildViewController:vc1];
vc2 = [[UIViewController alloc] init];
[self addChildViewController:vc2];
vc3 = [[UIViewController alloc] init];
[self addChildViewController:vc3];
vc4 = [[UIViewController alloc] init];
[self addChildViewController:vc4];
vc5 = [[UIViewController alloc] init];
[self addChildViewController:vc5];
vc6 = [[UIViewController alloc] init];
[self addChildViewController:vc6];
}
return self;
}
- (void)dealloc
{
[vc1 removeFromParentViewController];
vc1 = nil;
[vc2 removeFromParentViewController];
vc2 = nil;
[vc3 removeFromParentViewController];
vc3 = nil;
[vc4 removeFromParentViewController];
vc4 = nil;
[vc5 removeFromParentViewController];
vc5 = nil;
[vc6 removeFromParentViewController];
vc6 = nil;
}
- (void)switchFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
if (fromViewController) {
[fromViewController.view removeFromSuperview];
}
[self.view addSubview:toViewController];
toViewController.view.frame = self.view.bounds;
}
Avez-vous tous avez des idées de ce que je fais mal?
frame
comme étant à self.view.frame
, donc je ne comprends pas d'où le parent de la vue que vous seriez en montrant ce contrôle onglet.C'était juste un super exemple rapide de ce que mon code est en train de faire, il n'est donc pas 100% pensé. Dans mon application pratique il y a des onglets qui courent le long de la côte à la verticale, et puis il y a une vue dans la vue principale contrôleur de l'enfant-vue-contrôleur de la vue sont mis en, et leur image est réglée sur childViewController.frame = contentContainerView.limites;
Qui fait sens. À première vue, en regardant un exemple de confinement où il prenait tout l'écran vient de me demander si le confinement a été nécessaire. On dirait que vous avez un bon plan, si. Désolé de vous harceler. 😉
OriginalL'auteur miken.mkndev | 2012-12-12
Vous devez vous connecter pour publier un commentaire.
Comme je le soupçonnais, le problème n'est pas lié à la vue-contrôleur de confinement code en question, mais plutôt l'ajout des observateurs (qui vous discutez dans votre réponse à cette question):
Et que vous avez essayé de l'enlever avec
Donc, il y a deux problèmes:
Si vous utilisez
addObserverForName:object:queue:
, ce n'est pas la bonne façon de supprimer cet observateur. Au lieu de cela, définir une propriété de garder une trace de l'observateur:Ensuite enregistrer une référence à ce qu'observateur lors de sa création:
Et quand vous voulez l'enlever, utiliser cette référence:
Faire en sorte que l'observateur peut être éliminé correctement.
L'échec de l'enfant en vue de contrôleurs pour être libérée lors de cet observateur était en place signifie que ce bloc que vous avez passé à
addObserverForName:object:queue:
doit d'avoir une référence àself
. Si vous avez essayé de supprimer cet observateur correctement (comme illustré ci-dessus) dansdealloc
, vous auriez encore un fort cycle de référence (anciennement connue sous le nom de conserver cycle). Ce problème est résolu dans un certain nombre de façons, mais la plus robuste modèle est d'empêcher le fort de cycle de référence, en premier lieu, à l'aide de laweakSelf
modèle:Ma réponse est ci-dessous:
Tout Srikanth est juste qu'après
addChildViewController
, vous devriez appelerdidMoveToParentViewController:self
et avantremoveFromParentViewController
vous devriez appelerwillMoveToParentViewController:nil
. Mais ce n'est pas votre problème. En fait, j'ai utilisé une variante de votre code (même sans ledealloc
), et les enfants les contrôleurs sont libérés de l'amende.Ligne de fond, je soupçonne votre problème réside ailleurs, probablement un cycle de conserver quelque part. Par exemple, avez-vous des enfants ont une forte référence à la mère? Utilisez-vous récurrents timers? Vous faites référence à un certain nombre d'onglets. Vous n'êtes pas à l'aide d'une barre d'onglet contrôleur, êtes-vous? Il faut que ce soit quelque chose comme ça.
[Reportez-vous à la révision de l'histoire si vous voulez voir le reste de l'original de la réplique avec des extraits de code et des petits détails sur l'OP de l'exemple de code]
OriginalL'auteur Rob
Ce n'est pas le moyen d'ajouter et de retirer les enfants des contrôleurs de vue
est la façon de supprimer et d'ajouter que c'est
OriginalL'auteur Srikanth
Après des heures et des heures à essayer de comprendre ce qui se passait, j'ai enfin trouvé ce qui était la cause de mes enfant de voir les contrôleurs de libérer correctement.
Chaque vue-contrôleur a la suite de la notification déclaré à chacun afin qu'ils puissent répondre à divers événements.
S'avère, pour quelque raison que a été de garder mon point de vue, les contrôleurs de libérer correctement. Je devine que cela a ajouté de la vue-contrôleur à la NSNotificationCenters observateur de la liste, et n'a pas été supprimé quand j'ai fait la ligne suivante.
Donc pour résoudre mon problème j'ai juste changé la notification de s'inscrire comme ci-dessous.
Je n'ai aucune idée de pourquoi la façon dont j'ai été l'enregistrement de la notification n'était pas en permettant à mon point de vue, contrôleur de libérer correctement, mais cela semblait avoir fixé. Si quelqu'un dispose d'aucune information sur les raisons de ce problème arriverait-il alors s'il vous plaît laissez-moi savoir.
Merci!
OriginalL'auteur miken.mkndev