2012-09-26 83 views
47

也許這是一種不好的做法,但是從我閱讀的文檔中,我得到了有關在viewDidLoad方法內部初始化對象的建議,並且在viewDidUnload中沒有它。iOS6 viewDidUnload已過時

例如,如果您有類似增加觀察員

[[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(filterready:) 
               name:@"filterReady" 
               object:nil]; 

現在我沒有方法來刪除觀察員,但是viewDidLoad中成爲圖如圖每次從而導致具有多叫觀察員在一段時間後運行,然後選擇器被多次調用。

我可以通過將一些清潔劑移入viewDidDisappear方法來解決這個問題,但是現在我有些疑惑,如果我做正確的事情。

在我的示例中,我有一個正在控制自己的subnavigations多個導航控制器,但dealloc中絕不會爲他們,即使他們沒有被引用

回答

89

您應該使用 - (void)didReceiveMemoryWarning- (void)dealloc方法。

在iOS 6中,UIViewController的viewWillUnload和viewDidUnload方法現在已被棄用。如果您正在使用這些方法來釋放數據,請改用didReceiveMemoryWarning方法。如果未使用視圖控制器視圖,也可以使用此方法釋放對視圖控制器視圖的引用。在執行此操作之前,您需要測試視圖不在窗口中。

所以,你應該檢查一下你的看法是在窗口中,然後再刪除您的觀察者在didReceiveMemoryWarning

+0

這可能是正確的答案。仍然很奇怪,他們刪除了這條消息。我通過跟隨Paul Hegarty的幻燈片學習了使用SDK,當然他們仍然適用於iOS5。今年我會檢查他更新的幻燈片,也許他在這方面提供了一個很好的暗示。 – Hons

+2

@Hons它根本就不奇怪 - 「viewDidUnload」顯式地根據文檔,僅在因存在內存警告而卸載視圖時才調用。如果你在'viewDidLoad'中添加了一個觀察者,並且只在'viewDidUnload'中刪除了它,那麼很多時候你將會被刪除而不刪除它。這將在通知中心留下一個懸掛指針,幾乎肯定會在稍後發生崩潰。 – Tommy

+0

如何檢查您的視圖是否在窗口中? – zakdances

4

爲什麼不直接刪除該功能的dealloc觀察者? 如果你正在使用ARC,請不要調用[super dealloc]

如果你查看controller dealloc函數沒有被調用,那麼你需要發現這是爲什麼。也許你有一個NSTimer在ViewController上運行,當你彈出視圖時,這會導致dealloc不被調用。或者視圖被保留在其他地方。

+0

viewDidUnload的整點是,你可以卸載視圖和釋放的東西,而視圖控制器仍然存在 – user102008

+0

在iOS 6中以節省內存,UIViewController中的viewWillUnload和viewDidUnload方法現在已經過時.... –

+0

因此,你不該不使用dealloc方法。因爲對象還沒有準備好被銷燬。 – Craimasjien

9

亞歷克斯回答是好。但我喜歡適當的配對。因此,除非認爲需要通知的時候它甚至沒有見過,我通常在viewWillAppear中和viewDidDisappear

+0

viewDidUnload在視圖被卸載時被調用,而viewDidDisDar在視圖消失時被調用。必須在viewDidUnload方法下取消註冊的通知,現在自iOS 6.0開始,必須使用didReceiveMemoryWarning或dealloc註銷 –

12

首先,即使viewDidUnload並沒有過時,你必須有註銷該通知在viewDidUnload補充通知AND dealloc。即使在iOS 6之前,大多數情況下都不會調用viewDidUnload;只在低內存的情況下。因此,如果您以前只在viewDidUnload而不是dealloc之前,它不會被註銷,並且它可能會在解除分配並收到通知時崩潰。所以你必須先把它放在dealloc之前,因爲它能正常工作。其次,如果你以前做得正確,那麼你不需要做任何額外的工作來讓它在iOS 6中正常工作。iOS 6的唯一區別是視圖不再被卸載(即使在低記憶狀況)。所以當你沒有遇到內存不足的情況時,它與iOS 5中的一樣。由於意見沒有被卸載,所以viewDidLoad只會被調用一次,所以您的通知只會被註冊一次。它將在dealloc中未註冊,因爲您必須已將其設置爲正常工作。