Ios 更改UIWindow的rootViewController

Ios 更改UIWindow的rootViewController,ios,uiviewcontroller,uiwindow,rootview,Ios,Uiviewcontroller,Uiwindow,Rootview,当我的应用程序首次加载时,我将我的ui窗口的rootViewController属性设置为controllerA 在我的应用程序中,我选择将rootViewController更改为controllerB 问题是,有时当我在controllerB中进行翻转转换时,我会看到controllerA后面的视图。由于某些原因,该视图不会被删除。更令人担忧的是,在将rootViewController设置为controllerB之后,controllerA的dealloc方法从未被触发 在切换到contr

当我的应用程序首次加载时,我将我的
ui窗口的
rootViewController
属性设置为
controllerA

在我的应用程序中,我选择将
rootViewController
更改为
controllerB

问题是,有时当我在
controllerB
中进行翻转转换时,我会看到
controllerA
后面的视图。由于某些原因,该视图不会被删除。更令人担忧的是,在将
rootViewController
设置为
controllerB
之后,
controllerA
dealloc
方法从未被触发

在切换到
controllerB
之前,我尝试手动删除
UIWindow
的子视图,这解决了在后台查看
controllerA
视图的问题,但是
controllerA
的dealloc仍然没有被调用这里发生了什么事???

苹果医生说:

根视图控制器提供窗口的内容视图。将视图控制器指定给此属性(以编程方式或使用Interface Builder)会将视图控制器的视图安装为窗口的内容视图。如果窗口具有现有视图层次结构,则在安装新视图之前将删除旧视图

更新

以下是我的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;
}

问题可能出在您的ControllerA或ControllerB实现中,它们可能会在代码中保留“self”,因此ARC无法自动解除锁定您的ViewController。你能发布一下ControllerA和ControllerB的实现吗。

结果是有两个独立的问题。1) 我在控制器a中有一个保留周期,所以它永远不会被释放。其次,要更改根视图控制器,必须先删除windows子视图(即使文档中另有建议)


loginNavigationController=nil

这是apple的错误,我们假设ViewControllerA是当前的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;
}

如果将窗口的rootViewController重置为此代码,ViewControllerA的视图将永远不会解除锁定。

一个更简单的解决方案是将新窗口的
背景色设置为
.white
或任何颜色。默认值为nil,这将生成透明背景。这就是为什么旧窗口(新窗口的顶部可见)被看穿的原因。

你能为你的
应用程序提供代码吗:didFinishLaunchingWithOptions:
方法在你的应用程序代理中?愚蠢的问题,但是当你按下第二个控制器时,你是否将
控制器设置为零?如果没有,则不会解除锁定。(我假设你是)我从来没有保留过指向controllerA的指针,所以不确定我会将什么设置为nil。@Cezar刚刚用我的应用程序委托代码的浓缩版本更新了这个问题,这可以解释为什么没有调用dealloc。但是为什么controllerA的视图仍然可以在controllerB后面看到呢。更改根视图控制器是否会从窗口中删除controllerA的视图?
// 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;
}