簡體   English   中英

UIView的addSubview真的保留了視圖嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM