2010-09-18 38 views
1

我有一個TabView應用程序,其TabView應用程序具有NavView作爲視圖之一。這個視圖有一個帶有TableView的子視圖來保存事件。我已啓用導航欄右上角的「添加」按鈕,並將IBAction分配給按鈕。針對UINavigationController的推式重複調用會導致訪問錯誤

目標是顯示一個頁面來添加一個新的事件,這個事件是在我實例化一個我的子類控制器類的實例時加載的一個NIB文件定義的。我也從父導航控制器傳遞managedObjectContext。

這是第一次工作,但第二次按「添加」按鈕時,我得到一個EXC_BAD_ACCESS錯誤。我已經通過調試將控制器推到導航控制器上,並且我確認這是發生異常的地方。我已經閱讀了文檔,它說導航控制器會通過點擊導航欄頂部提供的「後退」按鈕來彈出控制器。我也知道,如果我嘗試將相同的視圖推入堆棧,將發生未處理的異常。我甚至試圖在推動清除堆棧之前回彈到根目錄,但仍然在第二次推入時得到異常。

我應該手動彈出這個(即導航「後退」按鈕實際上並沒有彈出這個)在別的地方?我也確認nav控制器和新實例化視圖控制器的實例都不是空的。

下面是添加按鈕的代碼片段:

- (IBAction) addEvent: (id)sender { 

// Here we'd instantiate an instance of our Add Event Controller to show the form that allows us to enter a new event. 

// We'd add the context to the class from here so that it can get to our Core Data 


    EventEntryViewController *fvController = [[EventEntryViewController alloc] initWithNibName:@"AddEventView" bundle:nil]; 

fvController.managedObjectContext = self.managedObjectContext; 

[self.navigationController pushViewController:fvController animated:YES]; 

[fvController release]; 

fvController = nil; 

} 

感謝您的幫助。

更新:

好吧,我已經停止發生異常。我嘗試了一個非常簡單的視圖,沒有任何內容,也沒有IBOutlets或IBActions和一個沒有屬性的控制器類。這工作,所以我覺得它必須是我的EventEntryViewController問題。它沒有做太多的工作,後面的跟蹤顯示它在顯示視圖的內部中死去,所以我甚至沒有進入loadView方法,更不用說我的代碼的其他部分了。我有一些已經在上一次加載中初始化的類屬性,並且作爲一個好公民,我在viewDidUnload()中釋放了它們,並在dealloc()中釋放它們。當我註釋掉我的類屬性的dealloc時,它工作正常!

我對此感到困惑,並把NSLog()行放在viewDidLoad(),viewDidUnload()和dalloc()中。這裏有兩個推序列的結果後,我拿出我的課的dallocs屬性:

2010-09-18 20:17:46.224 myFuel[6435:207] EventTableNavViewController: viewDidAppear 
2010-09-18 20:17:51.391 myFuel[6435:207] **EventEntryViewController**: View Did Load // loading up my class 
2010-09-18 20:17:53.954 myFuel[6435:207] EventTableNavViewController: viewWillAppear 
2010-09-18 20:17:54.314 myFuel[6435:207] EventTableNavViewController: viewDidAppear 
2010-09-18 20:17:54.315 myFuel[6435:207] **EventEntryViewController**: dalloc  // after the class should have been popped 
2010-09-18 20:18:02.803 myFuel[6435:207] **EventEntryViewController**: View Did Load //loading up my class 
2010-09-18 20:18:08.134 myFuel[6435:207] EventTableNavViewController: viewWillAppear 
2010-09-18 20:18:08.494 myFuel[6435:207] EventTableNavViewController: viewDidAppear 
2010-09-18 20:18:08.495 myFuel[6435:207] **EventEntryViewController**: dalloc // after the class should have been popped 

我失去了一些東西在這裏?該視圖不應該調用viewDidUnload()來釋放類屬性嗎?我可以看到dealloc被調用,但我在哪裏釋放這些?

回答

0

基於你所說的一些事情,雖然我不清楚你到底在做什麼。

首先,viewDidUnload:不保證被調用。一般來說,只有當你的視圖控制器卸載它的視圖來響應內存警告時纔會被調用。因此,您保留的任何內容在viewDidLoad:或掛鉤的IBOutlet都應在viewDidUnload:dealloc中發佈。

第二,你說你「釋放他們在dealloc」參照你的「類屬性」,我認爲你實際上是在其他對象上調用dealloc。如果是的話......不要這樣做。您只能在保留的對象上撥打release,並且在您直接致電dealloc時很少有實例。這是因爲dealloc將在最後一次發佈時在對象的release實現中調用。這是保留/釋放系統的重點。

+0

謝謝。我一直在閱讀Objective-C中的內存管理,尤其是在iOS框架中。我必須深入瞭解舊式MS COM世界中引用計數的突觸,以便燈泡熄滅。清楚的是,在正常的操作中,dealloc被調用,並且我釋放(如果它是對象的最後一個引用)將會得到GC。在內存警告中,viewDidUnload將被調用,並且那裏的版本將允許GC清理它。問題是viewDidUnload和dealloc在最後一種情況下被調用,隨後的版本會導致異常? – mcgski 2010-09-19 02:25:24

+0

當您在'viewDidUnload:'內部釋放時,請確保也將引用設置爲'nil'。然後,在你的'dealloc'中調用'release'時,你不會在懸掛參考上調用release。例如,如果你有'IBOutlet UILabel * label',從'viewDidUnload:'你可以執行:'[label release]; label = nil;'和'dealloc'中的代碼相同。如您所知,您可以安全地將消息發送到'nil'引用,這就是爲什麼'dealloc'中的發行版是安全的。 – imaginaryboy 2010-09-19 03:14:49

相關問題