IOS UIImage 內存細節


最近的一個項目,有大量的scrollView+imageView,當iPad啟動較多程序,再啟動自己的這個程序的時候,就爆內存退出了~~

后來把所有的生成圖片的方法,全部由imageNamed改成了imageWithContentsOfFile。

再運行,比之前好了不少,但是log還是會出現內存警告的信息,level 1,只是程序沒有掛掉。

再在所有釋放scrollView的子view的地方,把imageView.image設置為nil。

再運行,就沒有警告log出現了~~

 

imageNamed是會把讀取到的image存在某個緩存里面(我也不知道是哪個,但是它會。這樣內存等於多用了一份~),第二次讀取相同圖片的話系統就會直接從那個緩存中獲取(更快?),從某種意義上好像一種優化……但是imageNamed讀取到的那個圖片似乎不會因為Memory Warning而釋放,所以用這個會導致在內存不足的時候閃退。imageWithContentsOfFile則是一個比較直接的讀取,不會被存進某緩存,第二次讀取相同圖片也就是重新讀取一遍。但是imageWithContentsOfFile讀取的圖片在Memory Warning的時候就會被釋放,然后只有當前在用的那幾個會被重新讀取,所以節約了內存~
和imageView.image = nil無關
有關系的是 imageNamed這個方法是會緩存UIImage的 (即使相關的imageView已經析構) 

摘錄一段:
對於大圖片,慎用imageNamed這種方法來返回UIImage。

       理由是通過這個方法得到的UIImage是一直緩存在內存中,直到程序結束為止——這和我原先以為的系統會做一個引用計數,如果在引用計數為0的情況下自動清除該塊內存的想法不一致。而且值得一提的是所有用IB在xib文件內設置圖像的方法都是調用imageNamed這個方法,也就是說:這些內存在程序結束之前是一直保留着的,對於某些比較吃內存的應用就需要好好規划一下了。不過UITableViewCell這種需要重用的控件就很需要它了。

 

請告訴我正確的方式ALLOC一個UIImage到內存中,並釋放它的iphone -

Using Instruments, I keep on getting pointed to a memory leak with a UIImage.我一直在使用儀器,越來越指出,一個UIImage內存泄漏。 
I think I'm assigning and releasing the memory correctly.我想我分配和釋放內存正確。The leaked object in instruments is described as NSConcreteData泄漏的對象文書中被描述為NSConcreteData

Is the following the correct way to assign and release a UIImage?按照正確的方式來分配和釋放一個UIImage?

UIImage* flagimg = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]]; [flagimg release]; flagimg =nil; 
 

  • [UIImage imageWithData:] returns an autoreleased object, which should not be released by you again. [UIImage imageWithData:]返回一個自動釋放的對象,它不應該被釋放,你再次。 So this code snipped contains not a memory leak but the opposite, a double free (in the worst case).所以這個代碼片斷的,包含不是內存泄漏,但相反,雙重釋放(在最壞的情況下)。

    Note that Instruments sometimes generates false positives and/or reports memory leaks in the Foundation itself (yep, they make mistakes too :-).需要注意的是儀器有時會產生假陽性和/或報告內存泄漏基金會本身(是的,他們會犯錯誤太:-)。

    The fastest way to alloc/release an object is to avoid convenience initializers (like imageWithData:) and instead to something like最快的方式是為了避免分配/釋放一個對象方便的初始化(如imageWithData :)喜歡的東西,而

    推薦使用顯示alloc 的方式使用對象。這樣方便進行釋放。因為隱式調用如“imageWithData”返回的是一個autorelease對象,它要等autoreleasePool池來進行釋放。
    NSData* data = [[NSData alloc] initWithContentsOfURL:url]]; 
    UIImage* img = [[UIImage alloc] initWithData:data]; 
    [data release]; 
    // use your image 
    [img release];

    This will allocate and release your object right away and not wait until the autorelease pool is cleaned.這將分配和釋放你的對象,而不是等到autorelease池清洗。

    But please note too, that a memory leak is generally not memory that is not yet freed, but that is lost and cannot be freed anymore , so an object which will be deallocated by the autorelease pool is not considered a memory leak.但也請注意,內存泄漏一般是沒有尚未釋放的內存,但丟失,不能再被釋放 ,所以一個對象,該對象將被釋放autorelease池不被認為是內存泄漏。

  • both imageWithData and dataWithContentsOfURL return autoreleased objects, so you should have no memory leaks in that code snippet. imageWithData和autoreleased對象dataWithContentsOfURL回報,所以你應該有沒有內存泄漏的代碼片段。

    Since flagimg is returned autoreleased, your [flagimg release]; call is not needed; you're over-releasing that object. ,由於flagimg返回自動釋放,你的[flagimg release];不需要調用的,你是過度釋放該對象。

  • as a general rule you can say作為一般規則,你可以說

    if you create an object an theres a "init","copy" or "retain" in it, you have to release it.如果你創建了一個對象,一個世界上的“初始化”,“復制”或“保留”中,你必須釋放它。 if not, you get an autoreleased object.如果沒有,你得到一個自動釋放的對象。

    thats not always true, but in most cases那並不總是正確的,但在大多數情況下

     

     

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM