問題描述
我有以下用于縮放圖像的代碼片段.這是在一個循環中,為每次傳遞創建和排出一個自動釋放池.此代碼在 iOS5.0 的模擬器、iPad 上的 iOS4.3 或模擬器中運行良好,但在 iPad1 上的 iOS5.0.1 上,經過 50-60 次后,drawInRect 開始消耗永遠不會釋放的內存.我一直在從輔助線程調用它,但現在在主線程上調用縮放操作.
I have the following code fragment that I use to scale images. This is in a loop that creates and drains an autorelease pool for each pass. This code works fine in the simulator in iOS5.0, in iOS4.3 on iPad or simulator, but on iOS5.0.1 on an iPad1, after 50-60 passes, drawInRect starts consuming memory that never gets released. I had been calling this from a secondary thread, but now invoke the scaling operations on the main thread.
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
是我做錯了什么還是 iOS5.0.1 的錯誤?
Am I doing something wrong or is this an iOS5.0.1 bug?
更新:我已經嘗試了很多測試.我已經能夠證明用 XCode 4.0 編譯的完全相同的代碼在同一臺 iPad 上運行良好.使用 XCode 4.2.1 編譯的相同代碼會導致內存不足.此縮放例程正在后臺線程中調用.我使用較低級別的核心圖形調用編寫了一個不同的縮放例程.XCode 4.0 不會泄漏,但在我的 XCode 4.2.1 應用程序中會泄漏.在獨立項目中運行的完全相同的例程和調用樹似乎不會在 XCode 4.2.1 上泄漏(大量)內存.我正在等待 Apple 關于這個的消息.同時,我需要使用 XCode 4.我擁有的唯一安裝映像需要 Snow Leopard,這意味著我正在使用我的 5.5 年舊機器.謝謝
Update: I've tried many tests. I have been able to prove that the exact same code compiled with XCode 4.0 runs fine on the same iPad. Same code compiled with XCode 4.2.1 causes an out of memory condition. This scaling routine is being invoked in a background thread. I wrote a different scaling routine using lower level core graphics calls. It doesn't leak with XCode 4.0 but does leak when in my application with XCode 4.2.1. The exact same routine and invocation tree run in a stand alone project does not appear to leak (much) memory on XCode 4.2.1. I'm waiting to hear from Apple on this one. In the mean time I need to use XCode 4. The only install image I have requires Snow Leopard which means I'm using my ancient 5.5 yr old machine. Thanks
2012 年 1 月更新這似乎僅在應用程序從 XCode 中啟動時才會發生.在 iPad 上啟動的相同可執行文件沒有泄漏.具有相同例程的不同應用不會出現泄漏.
Update 1/2012 This only seems to occur if the app is started from within XCode. Same executable started on the iPad does no exhibit the leak. A different app with the same routine does not exhibit the leak.
我已向 Apple 打開了一份錯誤報告,并向他們發送了一個重現該問題的項目.我預計它不會很快得到解決,但它似乎并不像我最初想象的那樣普遍.
I've opened a bug report with Apple and have sent them a project which reproduces the problem. I don't expect it to be resolved anytime soon, but it doesn't seem as pervasive as I originally thought.
2012 年 6 月更新盡管已向 Apple 發送了一個重現該問題的最小項目,但他們聲稱無法重現該問題并且沒有取得任何進展.
Update 6/2012 Despite having sent Apple a minimal project which reproduced the problem, they claim not to be able to reproduce the problem and are not making any progress on it.
推薦答案
我相信我終于找到了內存泄漏的原因.在進行一些核心數據插入時,我發現了類似的行為.循環,創建許多被釋放的對象.在 iPad 上運行時,內存使用量會上升,但在應用程序因內存不足而崩潰之前沒有明顯的泄漏.但是當從設備啟動時,它運行沒有問題.
I believe I have FINALLY found the cause of the memory leak. I discovered similar behavior when doing some Core Data inserts. Looping, creating many objects that are released. When run on iPad, memory usage goes up although no leak is evident until the app crashes out of memory. But when initiated from the device, it runs without a problem.
我突然想到它是從 Xcode 開始的.必須是項目中的調試設置.
It occurred to me that its something about the way its being started from Xcode. Must be a debug setting in the project.
原來問題是由于在調試時使用 NSZombieEnabled
引起的.要在 Xcode 4 中禁用此設置,請右鍵單擊方案,即 app>targetDevice,編輯方案,選擇調試操作,參數選項卡.要啟用 NSZombieEnabled
,需要使用該名稱創建一個值為 YES 的環境變量,并啟用該變量.要禁用它,請取消選中該復選框.
Turns out the problem was caused by having NSZombieEnabled
while debugging. To disable this setting in Xcode 4, right click on the schemes, ie app>targetDevice, edit the scheme, select the Debug action, arguments tab. To enable NSZombieEnabled
, an environment variable is created with that name with a value of YES and the variable is enabled. To disable it, uncheck the checkbox.
NSZombieEnabled
用于確定您是否嘗試釋放已釋放的對象.為此,環境會跟蹤所有已發布的對象.這會消耗內存,表現為內存泄漏.
NSZombieEnabled
is used to determine if you attempt to release an object that has already been released. To do this, the environment is keeping track of all released objects. This is consuming memory which appears as a memory leak.
禁用此功能后,我的應用程序在 iPad1 上被殺死之前會快速增長超過 115MB,現在可以愉快地坐在 24MB 上,沒有內存泄漏.
Once I disabled this, my app that used to quickly grow over 115MB before being killed on an iPad1 now happily sits at 24MB with no memory leak.
這篇關于iOS5.0.1 上的內存泄漏 drawInRect的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!