[英]Unbounded memory growth - iOS
在下面解決
我正在閱讀raywenderlich博客中的這篇文章: http ://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode,以了解儀器並弄清楚我是否在某些舊版本中做錯了什么項目。
我已經看到,在代碼的特定點上,當我顯示最終關閉的模式視圖時,分配的內存將保留在那里。 正如您在下圖中看到的。
執行將生成4個標記。 如您所見,在2n和3t標記之間顯示視圖,分配了新的內存。 但是在3t和4th之間,我稱為dismissViewController,視圖不再保留。 但是內存仍然分配。
創建的所有屬性都很強(可能不是最佳方法):
我有一個NSTimer,它在viewDidLoad方法中初始化,並在viewWillDisappear處設置為nil:
[self.secondTimer invalidate];
self.secondTimer = nil;
那么,您對發生的事情有任何想法嗎? 據我所知,即使屬性被聲明為強屬性,當UIViewController發布時,所有屬性也都將發布到。
編輯
感謝所有人,僅憑我提供的信息還不夠。
如您所見,QRViewController繼承自BaseViewController。
該控制器有一個定義為強存儲,糟糕的委托。
就是這樣。
在視圖控制器層次結構中, self.view
所有子視圖都具有strong
,因此self.view
下的所有內容(可能是您的IBOutlet
所有屬性)都可以切換為weak
。 但這可能無法解決問題。
可能對您有幫助的事實是,您擁有的任何block
都將該塊中使用的每個單個對象都保持為強壯,以確保該塊可以同時運行其代碼。 如果沒有任何東西可以阻止該塊(例如animationWithDuration:
:),那就不用擔心了。 但是,如果您擁有對象持有的任何塊(例如和對象的“完成塊”或任何其他創造性使用的塊),則該塊中的所有內容都會很strong
,並且您可能會以這種方式創建保留周期。 例如:呈現視圖控制器正在使用完成塊調用呈現的視圖控制器,在該塊中您使用self
。 現在呈現的VC正在保存要執行的塊,而該塊保留了呈現的VC。 被解雇時,您將最終獲得一個VC,該VC包含一個塊,該塊包含一個VC,該VC包含呈現的VC。
一個簡單的解決辦法是賦予塊一個weak
的版本self
和塊執行時,才使它strong
運行的塊(為了避免dealloc的同時運行塊)的時間:
__weak myViewController *weakself = self;
[self.someObject setBlockHandler:^(BOOL foo){
myViewController *strongself = weakself;
if (strongself) {
// Do whatever...
}
}];
很難精確地找出問題所在,但是通常當我遇到這種情況時,它最終成為一個(或幾個)“根本”罪魁禍首-您找到一個,將其清除,然后再清理許多其他太。 因此,您可以嘗試的一種策略是在Instruments數據中進行篩選以查找任何類型的“層次結構”(考慮應用程序的結構以及對象之間的關系),然后尋找更接近基礎的對象,然后進行交叉請參考您的代碼以查看它們是否可能具有保留周期或其他一些此類問題。
我要立即進行的一項更改是將IBOutlet
聲明從strong
更改為weak
。 在大多數情況下,對於層次結構內的對象, IBOutlet
屬性應該是weak
。 因此,如果說您在xib的主view
有一些UILabel
,則應該弱保留該標簽,以避免出現保留周期。 但是,如果說UILabel
作為xib中的根項獨立存在,那么它將需要一個strong
參考。 我將猜測您的大多數IBOutlet
(如果不是全部)都在層次結構中,因此請使其weak
然后重試。 它可能無法解決所有泄漏問題,但請查看是否有任何區別。
這稱為“ 廢棄內存” ,請檢查此鏈接 。
提示:如果要在視圖控制器之間導航,並且在閉包內執行導航,則應使用self
的weak
版本或unowned
版本,例如:
//Swift 2.1
//Performing naivgation on the main thread for responsiveness:
dispatch_async(dispatch_get_main_queue(), {[weak self] () -> Void in
if let weakSelf = self{
weakSelf.performSegueWithIdentifier("myOtherView", sender: weakSelf)
}
})
另外,關閉視圖控制器時也是如此:
dispatch_async(dispatch_get_main_queue(), {[weak self] () -> Void in
if let weakSelf = self{
weakSelf.dismissViewControllerAnimated(true, completion: nil)
}
})
上面發布的鏈接顯示了有關如何使用Xcode Instruments捕獲abanodend內存的實際示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.