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說起可能出線的各種死法