2012-07-03 83 views
0

我有一個B UIViewController,裏面有關閉按鈕。UIViewController查看錯誤

 -(IBAction) close:(id) sender 

從視圖 - 控制我目前在B視圖 - 控制這樣

[self presentViewController:B animated:YES completion:NULL]; 

那麼一切都OK,我可以打的關閉按鈕,裏面B.

但是,如果我這樣做

B* bcontrol=[[B alloc] init]; 
    [self.view addsubview bcontrol.view]; 

那麼這樣,如果我點擊關閉按鈕,就會產生EXEC_BAD_ACCESS錯誤。

這是爲什麼?有任何想法嗎?

回答

1

您正在使用ARC,我假設。

創建B控制作爲一個局部變量和不保持對它的引用,所以ARC釋放它,當你去掉其觀點。然後你的按鈕試圖在一個釋放的對象中觸發一個動作......並且你知道其餘的。

製作B中的強大的屬性,以便它總是在那裏,當你需要它的觀點。

+0

我假設如果他使用上面列出的代碼,他一定不能使用ARC,否則我會懷疑他會在視圖出現時立即得到異常,而不是在點擊'close'按鈕,不是嗎?我發現奇怪的是,他討論瞭如何改變我們如何創建B的觀點,但沒有提到他在「close」方法背後使用的代碼,也沒有提到用於呈現新視圖的兩種技術的代碼如何改變。 – Rob

+0

直到引起視圖控制器中的代碼執行時纔會出現錯誤。由於它不是控制器層次結構的一部分,它不會得到正常的「出現」回調。我可以相信,按鈕水龍頭是轉折點。 (我不知道這種從他們的控制器中取出意見並將它們交給不同的控制器的做法是從哪裏來的,但我希望它現在會停止!:) –

+0

是的,我不確定視圖控制器的東西多少將在視圖控制器本身超出範圍之前執行。看起來像所有最初的東西,例如'viewDidLoad','viewWillAppear','viewDidAppear'等發生在'B *'解除分配之前,但是用戶從該點開始的任何事情都會導致異常。 – Rob

0

你不爲你的close方法提供代碼。 close方法代碼將不得不更改以符合您轉換到此新視圖的方式。如果你有通過presentViewController查看控制器B,你會那麼想必回回歸A通過:

- (IBAction)close:(id)sender 
{ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

再考慮如果通過

B* bcontrol=[[B alloc] init]; 
[self.view addsubview bcontrol.view]; 

去到B控制器顯然,dismissViewControllerAnimated韓元」工作了。所以問題是你改變你的close方法。

但在開始之前,這個結構有兩個問題。首先,如果你在非ARC項目中這樣做,你會泄漏你的控制器。更糟糕的是,如果你用ARC做這個,你會得到異常,因爲控制器在超出範圍時會被釋放(如果你打開殭屍,你會看到有意義的錯誤)。這個問題的典型答案是製作A的B* bcontrol和ivar,或者做這樣的事情,這樣指向bcontrol的指針就不會被釋放。這解決了眼前的問題。

其次,更大的問題是,這整個結構(添加控制器的視圖另一個視圖的子視圖)通常不是一個好主意,因爲你的視圖控制器的層次結構和您的視圖層次是不同步的。 (有關這些問題的冗長討論,請觀看WWDC 2011 session 102 on View Controller Containment。)您可能無法獲得輪換事件。你不知道還會發生什麼(因爲iOS假設它可以瀏覽視圖控制器層次結構以便將消息傳遞給各種控制器)。底線,採取另一個視圖控制器的視圖並將它添加爲當前視圖的子視圖並不是一個好主意。你唯一一次這樣做的是,如果你正在做一個真正的視圖控制器遏制,並已完成addChildViewControllerdidMoveToParentViewController,你只是想獲得第一個視圖(見前面的視頻)。

但是,如果您決定做[self.view addSubview:bcontrol.view];構建,那麼顯然您不能在您的B的close方法中使用相同的dismissViewControllerAnimated。從A的角度去除B的觀點的合理方法是[self.view removeFromSuperView];。但是,如何確保您的A課程現在清理您最初創建的B實例,否則您將面臨一個挑戰,否則您將發生泄漏。

底線,這不是一個好主意。堅持presentViewController(你會忽略dismissViewControllerAnimated)或pushViewController(你會忽略popViewControllerAnimated)或使用視圖控制器遏制。鑑於您討論了「關閉」按鈕的想法,這意味着一個UI真的適用於presentViewControllerpushViewController模型。