2011-07-30 29 views
2

如果我有一個UIViewControllers的NSArray並將發佈發送到數組,那麼是否會爲每個UIViewControllers調用viewDidUnload或dealloc?或兩者都不?將發佈發送到UIViewControllers的NSArray?

下面是我在做什麼:

- (void) viewDidLoad { 
    UIViewController* profileController = [[ProfileController alloc] init]; 
    .......... 
    //all the other controllers get allocated same way 

    self.viewControllers = [[NSMutableArray alloc] initWithObjects: profileController, dietController, exerciseController, progressController, friendsController, nil]; 

    [profileController release]; 
    //other controllers get released same way .... 
} 

- (void) dealloc { 
    [viewControllers release]; 
    NSLog("DEALLOC!"); 
    //I know dealloc is being called 
    //what happens to the view controllers? 
} 

我把一個斷點在viewDidUnload和dealloc的方法每個視圖控制器,他們不會被調用。

回答

1

正如pgb所提到的,您正混淆了內存管理和視圖控制器生命週期這兩個概念。每當視圖控制器視圖被卸載時,viewDidUnload將被調用,這當然只會在視圖被加載時發生。在沒有顯示任何視圖控制器的情況下,您根本不應該看到viewDidUnload

你非常期待看到dealloc雖然叫!

你的問題是與viewControllers陣列的初始化:

self.viewControllers = [[NSMutableArray alloc] 
           initWithObjects: profileController, 
               dietController, 
               exerciseController, 
               progressController, 
               friendsController, 
               nil]; 

假設viewControllers是使用保留屬性的屬性,這將泄漏的陣列,且因此所有數組的內容。問題是你已經分配了一個可變數組(因此保留count = 1),然後你將它分配給viewControllers屬性,這將增加保留計數。

在您的dealloc方法中,您(正確地)釋放數組,但這隻會將保留計數遞減爲1。

我建議的修復方法是添加autorelease到上面的代碼:

self.viewControllers = [[[NSMutableArray alloc] 
           initWithObjects: profileController, 
               dietController, 
               exerciseController, 
               progressController, 
               friendsController, 
               nil] autorelease]; 

進行這項變更後,你應該會看到dealloc正在呼籲視圖控制器。您還應該期望看到viewDidUnload,因爲這些視圖控制器的視圖被卸載(例如,因爲它們在基於導航控制器的應用程序中從堆棧中彈出)。

+0

哇。我完全錯過了......你是完全正確的。我通常使用一個臨時變量,如NSMutableArray a = [[NSMutableArray alloc] init ...],然後[釋放],但是這次我保持簡潔並且錯過了它。謝謝 –

0

我在這裏看到的兩個問題,每個不調用的方法:

如果與 UIViewController相關的 view沒有被加載

viewDidUnload不會被調用。您基本上混合了兩個概念:內存管理(和對象生命週期)與視圖控制器生命週期。雖然你可以看到兩者之間的一些平行關係,但它們並不一定是相關的。

您是否在任何時候推動viewController以使其視圖可見?如果你不是,那麼viewDidUnload肯定不會被調用(因爲不會viewDidLoad)。

至於dealloc,如果在您釋放對象(並且您認爲對象應該是內存中的dealloc)之後未調用它,那是因爲您有內存泄漏。在代碼中,我可以很容易地看到在初始化代碼中的內存泄漏:

UIViewController* profileController = [[ProfileController alloc] init]; 
.......... 
//all the other controllers get allocated same way 

self.viewControllers = [[NSMutableArray alloc] 
           initWithObjects: profileController, 
               dietController, 
               exerciseController, 
               progressController, 
               friendsController, 
               nil]; 

profileController得到它retainCount撞到第一線,當你alloc它。稍後,當您將其添加到NSMutableArray時,陣列將retain它,再次碰撞它retainCount。爲了平衡這一點,你需要release兩次,但你只有release一次,在你的dealloc方法。爲了解決這個問題,我會改變你的初始化:

UIViewController* profileController = [[[ProfileController alloc] init] autorelease]; 
.......... 
//all the other controllers get allocated same way 

self.viewControllers = [[NSMutableArray alloc] 
           initWithObjects: profileController, 
               dietController, 
               exerciseController, 
               progressController, 
               friendsController, 
               nil]; 

這將添加缺少額外的release和平衡你的視圖控制器的retainrelease電話。

+0

在分配數組後,我確實釋放了profileController:[profileController release]; –

0

當您釋放數組時,它不會釋放它,如果沒有其他保留,則授予它處理權限。

同樣,如果數組被處理,每個元素內部都被釋放,但是對象可能被保留在別處,因此不能保證立即處理。

一般來說,像視圖或視圖控制器這樣的對象在被呈現時被UI邏輯保留,所以直接或通過數組釋放你的保留,不會導致它被處理,如果它被顯示(或例如在導航控制器的堆疊中)。