Difference between [UIImage imageNamed...] and [UIImage imageWithData...]?

Solution 1:

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.

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.

Solution 2:

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

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

Solution 3:

As the API reference of UIImage says :

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

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

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 .

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 .


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.

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.

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

Sorry for my poor English . May it be helpful.