2011-06-22 70 views
2

對於視圖控制器,你在Interface Builder中設置的任何網點必須釋放 和設爲零viewDidUnload,並且還必須在的dealloc被釋放。編程創建子視圖和viewDidUnload

(參見:When should I release objects in viewDidUnload rather than in dealloc?

其中一個最重要的原因,實施[viewDidUnload]是的UIViewController子類通常也含有視圖層次結構中的各種子視圖擁有引用。這些屬性可能已經通過IBOutlets從筆尖加載時設置,或內部編程loadView[加重點],例如。

我的問題是,我們真的需要實現viewDidUnload對於在的loadView編程方式創建(無界面生成器)在視圖層次子視圖?

回答

5

這取決於你是如何創建它們的,以及是否需要在別處引用它們。

例如:

- (void)loadView 
{ 
    [super loadView]; 

    UIButton *someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    someButton.frame = CGRectMake(0, 0, 50, 50); 
    [self.view addSubview: someButton]; 
} 

,因爲someButton被內的loadView自動釋放你不會需要實現viewDidUnload上述情況。

又如:

- (void)loadView 
{ 
    [super loadView]; 

    self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    someButton.frame = CGRectMake(0, 0, 50, 50); 
    [self.view addSubview: someButton]; 
} 

在這個例子中,你可能需要使用viewDidUnload,因爲你有另一參考someButton遊逛。您希望viewDidUnload釋放該按鈕並重置參考,以免您不正確地使用它並釋放內存。在這種情況下,你也想在dealloc方法中釋放按鈕,以防從不調用viewDidUnload。

+0

這是完全正確的!這個想法是,你的視圖控制器應該能夠通過許多loadView(+ viewDidLoad)/ viewDidUnload-Cycles而不會泄漏內存或訪問殭屍。最好的例子是標籤欄控制器中的VC - 它們被分配一個,然後在點擊標籤時通過loadView/viewDidUnload –

+0

不應該在自定義loadView方法中調用[super loadView]。代碼如下:self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen] .applicationFrame] autorelease]; –

+0

想解釋爲什麼五寶?我從來沒有調用[super loadView]的問題。 – hundreth

0

在您的dealloc方法中執行此操作。無法保證viewDidUnload將被調用。它通常只在控制器需要卸載視圖時被調用,例如,當有記憶警告時。另一方面,init/dealloc配對將始終被調用。

+0

我在** dealloc **中發佈我的子視圖。 *我也*必須發佈我的子視圖並將它們設置爲無視圖viewDidUnload **? –

+0

@Seth Lowenstein:這取決於。從文檔中:「您應該只爲稍後可以輕鬆重新創建的對象執行此操作,無論是在viewDidLoad方法中還是從應用程序的其他部分執行。不應該使用此方法來釋放用戶數據或任何其他不容易重新創建「 – csano

2

你肯定是應該是。但是,如果您查看Apple樣本,則會發現有時候他們只是使用dealloc。如果你知道你的對象在使用後的某個合理時間會被釋放,我認爲這是完全合理的。然而,我遵循這種模式,因爲viewDidUnload在某些特殊情況下可能不會被調用。其實我不叫釋放方法這麼長的名字:

-(void)releaseRetainedXibAndViewDidLoadObjects 
{ 
    self.myLabel = nil; 
    self.myImage = nil; 
} 

-(void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    [self releaseRetainedXibAndViewDidLoadObjects]; 
} 

-(void)dealloc 
{ 
    self.myObject = nil; 
    [self releaseRetainedXibAndViewDidLoadObjects]; 
    [super dealloc]; 
} 

你甚至可以從你的類繼承爲了簡化問題,應用特定視圖控制器對象做到這一點。

+0

在** viewDidUnload **和* dealloc **中調用相同的「釋放方法」是否明智?通常,我們將@property設置爲「(nonatomic,retain)」,因此爲您創建的setter釋放當前對象,然後保留該參數。也就是說,** viewDidUnload **中的'self.myProperty = nil;'做了類似'[myProperty release]的事情; myProperty = [nil retain];'...然後,在** dealloc **中,我們所做的就是'[myProperty release]'。 –

+0

使用我的模式是完全安全的,並且在dealloc中不需要以與viewDidUnload不同的方式做它。對於保留屬性self.property = nil等同於[property release],property = nil;儘管在dealloc中將它設置爲零並不重要,但如果您以後意外嘗試訪問它,它仍然是一個好主意。您應該減少冗餘以及必須定義相同功能的地方的數量。 –