![](/img/trans.png)
[英]UIWindow results in a black screen when changing the rootViewController
[英]Changing the rootViewController of a UIWindow
當我的應用程序首次加載時,我將UIWindow
的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;
}
事實證明有兩個不同的問題。 1) 我在控制器 A 中有一個保留周期,所以它永遠不會被解除分配。 其次,為了更改根視圖控制器,您必須首先刪除 Windows 子視圖(即使文檔另有建議)
問題可能出在您的 ControllerA 或 ControllerB 的實現中,它們可能會在代碼中保留“self”,因此 ARC 無法自動釋放您的 ViewController。 你能發布你的 ControllerA 和 ControllerB 實現嗎?
var loginNavigationController: OnBoardViewController?{
willSet{
if newValue == nil {
loginNavigationController?.view.removeFromSuperview()
}
}
}
loginNavigationController = nil
這是蘋果的 bug,我們假設 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 的視圖將永遠不會釋放。
一個更簡單的解決方案是將新窗口的backgroundColor
設置為.white
或任何顏色。 默認值為 nil,這會導致背景透明。 這就是為什么可以看到舊窗口(在其上可見新窗口)的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.