iOS 內存斗爭小史之 NavigationController


1、怎樣寫一個不泄漏的NavigationController頁面跳轉程序?

非arc模式下,假設有A、B兩個viewController,從A推到B,怎樣寫內存才能不泄漏?

A.m

-(IBAction)btnGoToViewControllerB:(id)sender
{
    ViewControllerB *aController = [[ViewControllerB alloc]init];
    [self pushViewController:aController animated:YES];
    [aController release];    //此處要釋放
}

 B.m

-(IBAction)btnGoToViewController1:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];    //執行完本句后,系統會自動調用B類的dealloc方法,釋放內存
}

我按照上面的步驟做的,為什么我的B類在pop時,系統沒有調用dealloc方法呢?呵呵,如果真像上面說的那么簡單,我就不寫這片博客了。接着往下看!

首先,你的例子是新創建的工程嗎,里面只有A B兩個controller,而且除了必要的代碼,沒加其它的控件。如果是,你不會遇到這樣的疑惑。是不是在網上down了一個工程來測試上面的代碼,還是在自己的原開發工程里調試的。呵呵,不賣關了。

* 一個對象的dealloc方法若想被系統自動調用,前提是拴在此對象身上的狗鏈子已經全部消失,即retainCount為0.(在內存管理時,不建議去人工計算retainCount大小,來判斷對象是否該釋放了。應該使用對象“所有權”的思想去理解內存管理)。

* 我們知道alloc \ copy \ retain 操作會讓你個對象被一個指針持有。但是,大家往往忽略對象本身self的賦值,也會被一個指針持有。如下:

self.tableView.delegate = self;                     //讓self被tableView.delegate 持有,需要顯示release 

我們的viewControllerB沒有如期被調用dealloc是因為這個對象還有指針持有它,還有狗鏈子拴着它呢!怎么釋放?所以,要想對象被即使釋放,請檢查工程內,是否有哪個指針還持有這個對象。alloc \copy \ retain\和 *** = self;全部都要檢查哦。

如果一個對象被一個指針,通過 *** = self;持有,那么應該在合適釋放比較合適呢。dealloc肯定不行,因為只有對象沒有持有者時系統才會進dealloc。一般地,應該寫在返回按鈕或其它頁面跳轉事件中。如下:

//返回 按鈕
-(IBAction)btnBackClicked:(id)sender
{
    [self.m_gridView.gridViewDelegate release];   //持有者 釋放所有權
    [self.navigationController popViewControllerAnimated:YES];
}

經驗:

1、查看一個對象沒有被及時釋放,要重點檢查其是否還有持有者。(用所有權地理念管理內存,而不是retainCount)

2、在實際編碼中,dataSource也持有了對象如下:

aGridView.gridViewDelegate = self;
aGridView.gridViewDataSource = self;

但是卻並不需要釋放。如果釋放了dataSource反而會引發過度釋放的問題。具體原因,歡迎朋友告知。

 

參考:

解決循環引用問題:  一次IOS開發內存泄漏問題      iOS5中UIViewController的新方法

內存使用狀態持續增長。。。(pop之前設置delegate為nil)   

由pushViewController說起可能出線的各種死法

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM