2014-10-28 90 views
2

我正在以編程方式創建所有顯示對象,並將它們添加到故事板場景子視圖中。切換故事板場景時從內存中移除對象

例如:

let button: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 160, height: 50)) 
self.view.addSubview(button) 

當改變故事板的場景,我遇到巨大的內存泄漏(內存使用每個場景變化之間幾乎翻了一番),這當然顯示了更改時,這些對象不會被自動刪除場景。我已經閱讀了Swift中有關垃圾收集的一些內容,但沒有在這個特定的用例上找到很多信息。

通過改變故事板的場景,我通過存在視圖控制器的意思是,像這樣:

self.presentViewController(targetController, animated: true, completion: nil) 

所以隨着中說,我的問題是:

1)刪除對象可以像這樣進行:

button.removeFromSubview() 
button = nil 

是否正確?

2)是否有辦法消除插入視圖的子視圖在一個循環中的任何對象,併爲其分配爲零完全刪除與該對象關聯的任何引用?我可以逐個刪除它們,但這是一項艱鉅的任務。

3)是否有改變場景後自動從內存中刪除對象?這將是最好的解決方案。

一個解決方案的例子將不勝感激。

在此先感謝。

+0

你在哪裏添加子視圖? viewDidLoad中? viewDidAppear?在裏面? – Acey 2014-11-24 22:56:05

+0

In viewDidLoad。謝謝 – PersuitOfPerfection 2014-11-26 14:50:46

回答

0

如果通過改變場景你的意思是要添加到堆棧中一個新的觀點,那麼這是我的理解是,以前的觀點仍然存在只是在等待被彈出堆棧的頂部,因此您的對象不應該被刪除。如果我有這個錯誤,有人會糾正我。無論如何,代碼從視圖中移除所有的對象是:

for sv in view.subviews { 
    sv.removeFromSuperview() 
} 
+0

我已添加更多信息。從我的測試中,在我沒有清除內存的用例中,因爲仍然存在對象的引用,但它自然會將它們從顯示中刪除。在發佈之前,我確實嘗試了這種方法,但無法刪除沒有幫助的對象。謝謝 – PersuitOfPerfection 2014-10-28 14:43:27

2

有些東西可能被澄清:是經由故事板(那些標記@IBOutlet)是弱加入

1)按鈕;你不需要將它們清零,因爲你對它們的引用不會將它們留在內存中。

2)presentViewController可能不會在您所期望的方式運行。最重要的是,不用替換現有的視圖控制器與新的視圖控制器;它從「陳述」新的視圖控制器舊的視圖控制器。爲了說明這一點,您可以從新的視圖控制器調用self.presentingViewController,它將爲您提供對前一個視圖控制器的引用;它仍然在記憶中。

然而,視圖控制器是不是超級大,他們有當他們沒有在屏幕上自己的意見卸載。但是,如果您在呈現視圖控制器中保留一些大型資源,這些資源將會持續存在。我建議通過在viewWillAppear/viewDidAppear(而不是viewDidLoad)中加載這些資源,然後將它們卸載到prepareForSegue:或viewDidDisappear中來解決這個問題(我認爲在didDisappear中存在一些長期存在的問題,並沒有始終如一地調用?我有某種心理國旗圍在那裏,但我不知道來源是什麼...)

或者,如果你真的想要做的是完全切換到新的根視圖控制器,你可以通過你的AppDelegate我們做到這一點.window屬性,如下所示:

let storyboard = UIStoryboard(named: "NewStoryboard", bundle: nil) 
let newVC = storyboard.instantiateInitialViewController 
UIApplication.sharedApplication().delegate.window.rootViewController = newVC 

雖然我不會過度使用,在首次啓動時可能會顯示教程的地方,然後希望加載普通視圖層次的地方,它非常有用。

+1

這是接近我正在尋找的答案。爲了進一步闡述,我並沒有通過故事板創建任何東西,除了我的視圖控制器之外,所有東西都是以編程方式創建的(我將它們添加到故事板並實例化它們,對於卸載對象,在這種情況下,循環遍歷子視圖?他們的引用呢?我需要添加每個對象到一個數組,所以我可以通過循環和零它們之後嗎?同樣的問題是任何變量是視圖控制器類的一部分我會喜歡一種方法來轉儲一切 – PersuitOfPerfection 2014-11-21 16:50:52

+1

要添加到我的上面的評論,循環通過子視圖似乎不夠,我仍然得到一個內存泄漏重複場景之間改變。這是我的理由要求其他人如何清除他們的引用也是,當以編程方式在我使用的其他框架中,標準的做法是在刪除對象後刪除引用,但可以通過循環訪問子視圖,刪除對象並將其視爲參考,因此我的困惑:) – PersuitOfPerfection 2014-11-21 16:53:15

+0

視圖控制器的視圖在視圖不再可見時被卸載。您的泄漏可能與保存在系統緩存中的圖像有關;請參閱http://stackoverflow.com/questions/20588338/ios-uiimage-storage-formats-memory-usage-and-encoding-decoding。 – cmyr 2014-11-21 17:23:31