web-dev-qa-db-fra.com

Changer le rootViewController d'une UIWindow

Lorsque mon application est chargée pour la première fois, j'ai défini la propriété rootViewController de ma UIWindow sur controllerA

Parfois, au cours de mon application, j'ai choisi de changer rootViewController en controllerB.

Le problème est que, parfois, lorsque je fais une transition inversée dans controllerB, je vois la vue de controllerA derrière celle-ci. Pour une raison quelconque, cette vue n'est pas supprimée. Ce qui est encore plus inquiétant, c’est qu’après avoir défini la méthode rootViewController à controllerB, controllerA, la méthode dealloc ne soit jamais déclenchée.

J'ai essayé de supprimer les sous-vues de UIWindow manuellement avant de passer à controllerB, ce qui résout le problème de voir les vues de controllerA en arrière-plan, mais le dealloc de controllerA n'est jamais appelé. Que se passe t-il ici????

Les documents sur les pommes disent:

Le contrôleur de vue racine fournit la vue du contenu de la fenêtre. L'affectation d'un contrôleur de vue à cette propriété (par programme ou à l'aide d'Interface Builder) installe la vue du contrôleur de vue en tant que vue de contenu de la fenêtre. Si la fenêtre possède une hiérarchie de vues existante, les anciennes vues sont supprimées avant les nouvelles.

METTRE À JOUR

Voici le code de mon AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self showControllerA];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)showControllerA
{
    ControllerA* a = [ControllerA new];
    self.window.rootViewController = a;
}

- (void) showControllerB {
    ControllerB* b = [ControllerB new];
    self.window.rootViewController = b;
}
25
aloo

Il s'avère qu'il y a deux problèmes distincts. 1) J'avais un cycle de conservation dans le contrôleur A, de sorte qu'il n'était jamais désalloué. Deuxièmement, pour changer le contrôleur de vue racine, vous devez d'abord supprimer les sous-vues de Windows (même si la documentation suggère le contraire).

10
aloo

Le problème peut provenir de votre implémentation de ControllerA ou ControllerB, ils peuvent conserver «auto» dans le code afin que ARC puisse automatiquement désaffecter ViewController. Pouvez-vous poster votre implémentation ControllerA et ControllerB.

1
ntus1017
var loginNavigationController: OnBoardViewController?{
    willSet{
        if newValue == nil {
            loginNavigationController?.view.removeFromSuperview()
        }
    }
}

loginNavigationController = nil

0
Ankish Jain

C'est le bug d'Apple, nous supposons que ViewControllerA est l'actuel rootViewController:

// ViewControllerA.m
- (void)buttonClick {
    [self dismissViewControllerAnimated:YES completion:^{
        // [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // OK
    }];

    [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // ViewControllerA's view will not dealloc 
}

// AppDelegate.m
- (void)resetRoot {
    ViewControllerB *controller = [[ViewControllerB alloc] init];
    self.window.rootViewController = controller;
}

Si vous réinitialisez rootViewController de la fenêtre avec ce code, la vue de ViewControllerA ne sera jamais traitée.

0
渺小的我