[UIImage imageNamed…]和[UIImage imageWithData…]之間的區別?

[英]Difference between [UIImage imageNamed…] and [UIImage imageWithData…]?


I want to load some images into my application from the file system. There's 2 easy ways to do this:

我想從文件系統將一些圖像加載到我的應用程序中。有兩種簡單的方法:

[UIImage imageNamed:fullFileName]

or:

或者:

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];

[UIImage imageWithData:imageData];

I prefer the first one because it's a lot less code, but I have seen some people saying that the image is cached and that this method uses more memory? Since I don't trust people on most other forums, I thought I'd ask the question here, is there any practical difference, and if so which one is 'better'?

我更喜歡第一個,因為它的代碼要少得多,但是我看到有人說這個圖像被緩存了,這個方法使用了更多的內存?因為我不相信大多數其他論壇上的人,所以我想在這里問一個問題,是否有什么實際的區別,如果有的話,哪個更好?

I have tried profiling my app using the Object Allocation instrument, and I can't see any practical difference, though I have only tried in the simulator, and not on an iPhone itself.

我嘗試使用對象分配工具對我的應用程序進行分析,但我看不到任何實際的區別,盡管我只是在模擬器中嘗試過,而不是在iPhone本身上。

8 个解决方案

#1


90  

It depends on what you're doing with the image. The imageNamed: method does cache the image, but in many cases that's going to help with memory use. For example, if you load an image 10 times to display along with some text in a table view, UIImage will only keep a single representation of that image in memory instead of allocating 10 separate objects. On the other hand, if you have a very large image and you're not re-using it, you might want to load the image from a data object to make sure it's removed from memory when you're done.

這取決於你對圖像做了什么。imageNamed:方法確實緩存圖像,但在許多情況下,這將有助於內存的使用。例如,如果你在表視圖中加載一個圖像10次並同時顯示一些文本,UIImage將只在內存中保留該圖像的一個表示,而不是分配10個單獨的對象。另一方面,如果你有一個非常大的圖像並且你沒有重新使用它,你可能想要從一個數據對象加載這個圖像,以確保它在你完成時被從內存中刪除。

If you don't have any huge images, I wouldn't worry about it. Unless you see a problem (and kudos for checking Object Allocation instead of preemptively optimizing), I would choose less lines of code over negligible memory improvements.

如果你沒有巨大的圖像,我不會擔心。除非您看到一個問題(以及檢查對象分配而不是預先優化的稱贊),否則我將選擇更少的代碼行而不是微不足道的內存改進。

#2


10  

In my experience [UIImage imageNamed:] has dramatically better performance, especially when used in UITableViews.

在我的經驗中[UIImage imageNamed:]有顯著更好的性能,特別是在UITableViews中。

It's not just the memory but also decoding the image. Having it cached is much faster.

這不僅是記憶,也是解碼圖像。緩存它要快得多。

#3


9  

As the API reference of UIImage says :

正如UIImage的API引用所說:

+(UIImage *)imageNamed:(NSString *)name

+(用戶界面圖像*)imageNamed:(NSString *)的名字

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

此方法在系統中查找具有指定名稱的映像對象並在該對象存在時返回該對象。如果一個匹配的圖像對象還沒有在緩存中,這個方法將從指定的文件加載圖像數據,緩存它,然后返回結果對象。

+(UIImage *)imageWithContentsOfFile:(NSString *)path

+(用戶界面圖像*)imageWithContentsOfFile:(NSString *)的道路

This method does not cache the image object.

此方法不緩存映像對象。

so,we can see that if you have a lot of same UI elements(such as UITableViewCell) that may use same image(often as an icons),and due to performance , of course we want to reuse the same image , so that we will save some memory for other use . Generrally the reused image is often used in the ui element that our user may operate on it lots of times . So it values for us to reuse it .So you can choose to use imageNamed method .

因此,我們可以看到,如果您有很多相同的UI元素(比如UITableViewCell),它們可能使用相同的圖像(通常作為圖標),而且由於性能的原因,當然我們希望重用相同的圖像,以便為其他用途保存一些內存。重用的映像通常在ui元素中使用,我們的用戶可以對其進行多次操作。所以我們需要重用它,所以你可以選擇使用imageNamed方法。

And on the other hand , in an application , there will be some UI element that will be there during the app's life cycle,such as a Button , a logo view , so these images used by these ui elements may also be there during the app's life cycle ,you wouldn't consider whether these image should be cache or not .So you can choose to use imageNamed method .

,另一方面,在一個應用程序中,會有一些UI元素,將在應用程序的生命周期中,比如一個按鈕,一個標志的觀點,所以這些圖像所使用的這些UI元素也可能在應用程序的生命周期中,你不會考慮是否應該將這些圖像緩存,所以你可以選擇使用imageNamed方法。


On the contrary,in an application , there are often some UI Elements that created dynamically. For example , our application support dynamic background , so that user can choose the background they like .And the background may be an image .So we may have a interface that list lots of different background (often show by use UIImageView) for user to choose ,we can name the list view MyBackgroundListView.So once the user chooses an background image , the MyBackgroundListView should be destroyed , because it has finishs its function .The next time the user want to change his/her background , we can create MyBackgroundListView again .So the images used by MyBackgroundListView shouldn't be cached , or our application's memory will run out .So this time you should use imageWithContentsOfFile method.

相反,在應用程序中,通常有一些動態創建的UI元素。例如,我們的應用程序支持動態背景,以便用戶可以選擇他們喜歡的背景,背景圖像,所以我們可能有一個接口列表不同的背景(通常是展示了使用UIImageView)供用戶選擇,我們可以MyBackgroundListView名稱列表視圖。一旦用戶選擇一個背景圖像,MyBackgroundListView應該被摧毀,因為它完成其功能,下次用戶想要改變他/她的背景,我們可以創建MyBackgroundListView再次所以MyBackgroundListView不應該使用的圖像緩存,或應用程序的內存將耗盡,所以這一次你應該使用imageWithContentsOfFile方法。

As the Apple's doc Supporting High-Resolution Screens In Views says

正如蘋果公司支持高分辨率屏幕的文檔所言

On devices with high-resolution screens, the imageNamed:, imageWithContentsOfFile:, and initWithContentsOfFile: methods automatically looks for a version of the requested image with the @2x modifier in its name. If it finds one, it loads that image instead. If you do not provide a high-resolution version of a given image, the image object still loads a standard-resolution image (if one exists) and scales it during drawing.

在具有高分辨率屏幕的設備上,imageNamed:, imageWithContentsOfFile:,和initWithContentsOfFile:方法自動查找請求的圖像的一個版本,其名稱為@2x修飾符。如果它找到一個,它就會加載那個圖像。如果您不提供給定圖像的高分辨率版本,圖像對象仍然會加載一個標准分辨率圖像(如果存在的話),並在繪圖期間縮放。

so you would worry about the image's search path for retina screen problem . IOS will help you deal with it.

所以你會擔心視網膜屏幕的搜索路徑問題。IOS將幫助你處理它。

Sorry for my poor English . May it be helpful.

對不起,我的英語不好。可能它是有益的。

#4


7  

If you don't want your image do be cached you can also use initWithContentsOfFile directly :

如果你不希望你的圖像被緩存,你也可以直接使用initWithContentsOfFile:

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
UIImage* yourImage = [[[UIImage alloc] initWithContentsOfFile:imagePath] autorelease];

#5


5  

I've also been told that [UIImage imageNamed:] does a little bit too much caching, and images are not often released. I was told to be careful of using it.

我還被告知[UIImage imageNamed:]做了太多的緩存,而且圖像不經常發布。我被告知要小心使用它。

#6


3  

imageWithData is useful when you store your image binary in a database or progressively downloading large image from the web.

當您將映像二進制文件存儲在數據庫中或逐步從web下載大型映像時,imageWithData非常有用。

#7


0  

I would not use imagenamed if your app has loads of big images which are not the same. I experienced app crashing due to using too much of it.

如果你的應用里有很多大的圖片,它們是不一樣的,我就不會使用imagenamed。我體驗過由於使用太多而導致的應用崩潰。

#8


-11  

I don't believe that the image gets cached at all, and I don't know why you are all saying that. UIImage is a subclass of NSObject which uses reference counters to keep track of the things that it is related to. So when you load an image it does that same thing. If you load the same image multiple times it will(or should) have only one copy of the image in memory and just increment the reference counter every time you have to use something with that image. By Reference Counters I mean that when the count gets to 0 it deletes itself. so "alloc", "retain" are each +1 to the count and "release" is -1. Not only is it a better way to manage memory but this style of programming also helps clean up memory leaks.

我不相信這個圖像會被緩存,我也不知道你們為什么這么說。UIImage是NSObject的一個子類,它使用引用計數器來跟蹤與它相關的事物。所以當你加載一個圖像時,它會做同樣的事情。如果您多次加載相同的圖像,它將(或應該)在內存中只有一個映像副本,並且每次您必須使用該映像時,只增加引用計數器。引用計數器的意思是當計數為0時,它會刪除自己。所以"alloc" retain"是每個+1的計數"release"是-1。這不僅是管理內存的更好方法,而且這種編程風格也有助於清理內存泄漏。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2008/11/25/eff1e24c33a80e48cd0aa2800b86afc.html



 
  © 2014-2022 ITdaan.com 联系我们: