[英]Does UIView's addSubview really retain the view?
我遇到了一個似乎暗示不同的情況。 在下面的代碼片段中,如果我刪除行:self.navigationController = nav,根控制器的視圖將不會顯示,向我建議addSubview可能實際上不會保留視圖,否則建議。 任何的想法?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.testViewController];
self.navigationController = nav; //<-- if this line is removed, test view won't show up
[window addSubview:nav.view];
[nav release];
}
這一行:
[window addSubview:nav.view];
不會立即向屏幕添加視圖。 它在一個可能不同的線程上的某個未來的運行循環中由OS顯示。 實際的實現我們無法確定。
這就是Apple定義委托方法(如viewDidAppear / viewWillAppear)的原因,否則我們就不需要它們,因為我們可以准確地知道這些事件何時發生。
此外,如您所說,添加子視圖確實保留了視圖。 但是,它沒有保留的視圖控制器或導航控制器。 由於導航控制器將保留任何添加的視圖控制器,因此我們不必使用ivar支持它們。
但是,您對導航控制器的引用必須超出方法的范圍。 或者根據您的代碼,它可以被解除分配或丟失其引用。
因此,您必須使用ivar保留對導航控制器的引用,並將其設置為:
self.navigationController = nav;
因此,即使nav.view包含指向testViewController.view的指針,該應用程序也沒有引用導航控制器,也沒有引用視圖。 結果是一個空白屏幕。
為了使這更加明顯,它不是保留/釋放問題,您實際上是在使用以下方法泄漏:
self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]];
您需要通過以下方式自動發布以平衡您的保留/釋放:
self.testViewController = [[[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]] autorelease];
因此,這意味着您的視圖從未在您運行此代碼時被解除分配。 這進一步向我們保證,您的問題確實是一個失去的參考。
問題可能不是視圖沒有保留,而是保留了控制器。
沒有這一行:
self.navigationController = nav
什么都沒有保留導航控制器。 讓視圖比控制器更長是很奇怪的。
對我來說這看起來不像是一個保留/釋放問題。 如果你注釋掉self.navigationController = nav;
你的視圖就不會出現self.navigationController = nav;
因為在下一行, [window addSubview:self.navigationController.view]
你的self.navigationController屬性將不會被設置。 它可能是零或者它會崩潰但是如果沒有更多的代碼就無法肯定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.