和之间的区别?

我想从文件系统加载一些图像到我的应用程序。 有两个简单的方法来做到这一点:

[UIImage imageNamed:fullFileName] 

要么:

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

我更喜欢第一个,因为它less了很多代码,但是我看到一些人说图像被caching了,而且这个方法使用了更多的内存? 由于我不相信大多数其他论坛上的人,所以我想我会问这个问题,有没有实际的区别,如果有的话,哪一个更好?

我已经尝试使用对象分配工具分析我的应用程序,并且我看不到任何实际的区别,尽pipe我只在模拟器中尝试过,而不是在iPhone本身。

这取决于你对图像做什么。 imageNamed:方法可以caching图像,但在很多情况下,这将有助于使用内存。 例如,如果您加载一个图像10次以在表格视图中显示一些文本,则UIImage将只在内存中保留该图像的单个表示,而不是分配10个单独的对象。 另一方面,如果你有一个非常大的图像,而不是重新使用它,你可能需要加载一个数据对象的图像,以确保它完成后从内存中删除。

如果你没有任何大的图像,我不会担心。 除非你看到一个问题(和检查对象分配,而不是抢先优化),我会select较less的代码行可以忽略不计的内存改进。

根据我的经验[UIImage imageNamed:]具有显着更好的性能,特别是在UITableViews使用时。

这不仅是内存,而且还解码image 。 caching起来要快得多。

正如UIImage的API参考所说:

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

此方法在系统caching中查找具有指定名称的图像对象,并返回该对象(如果存在)。 如果匹配的图像对象不在caching中,则此方法从指定的文件加载图像数据,将其caching,然后返回结果对象。

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

此方法不caching图像对象。

所以,我们可以看到,如果你有许多相同的UI元素 (如UITableViewCell)可能使用相同的图像(通常作为一个图标 ),并由于性能,当然我们想重用相同的图像 ,所以我们会节省一些内存供其他使用。 一般来说, 重复使用的图像经常用在我们的用户可能在其上操作很多次的UI元素中。 所以它值我们重用它。所以你可以select使用imageNamed方法。

另一方面,在一个应用程序中,在应用程序的生命周期中将会出现一些UI元素 ,例如Button,一个徽标视图,这些UI元素所使用的这些图像也可能在应用程序的生命周期,你不会考虑这些图像是否应该caching。所以你可以select使用imageNamed方法。


相反,在应用程序中,经常会有一些dynamic创build的UI元素 。 例如,我们的应用程序支持dynamic背景 ,所以用户可以select他们喜欢的背景 ,而背景可能是一个图像。所以我们可能有一个界面,列出了许多不同的背景 (通常使用UIImageView显示)供用户select,我们可以命名列表视图MyBackgroundListView 。所以一旦用户select一个背景图像MyBackgroundListView应该被销毁,因为它已经完成了它的function。下一次用户想改变他/她的背景,我们可以再次创buildMyBackgroundListView 。所以MyBackgroundListView使用的图像不应该被caching,否则我们的应用程序的内存将会用完。所以这次你应该使用imageWithContentsOfFile方法。

正如苹果公司的支持高分辨率屏幕视图说

在具有高分辨率屏幕的设备上, imageNamed:imageWithContentsOfFile:initWithContentsOfFile:方法会自动在名称中使用@ 2x修饰符查找所请求图像的版本。 如果find一个,它会加载该图像。 如果您没有提供给定图像的高分辨率版本,则图像对象仍会加载标准分辨率图像(如果存在),并在绘图期间对其进行缩放。

所以你会担心图像的视网膜屏幕问题的searchpath。 IOS将帮助你处理它。

对不起,我英文很差。 可能会有所帮助。

如果你不希望你的图像被caching,你也可以直接使用initWithContentsOfFile:

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

我也被告知, [UIImage imageNamed:]做了一些太多的caching,并且图像不经常被释放。 我被告知要小心使用它。

当您将图像二进制文件存储在数据库中或逐渐从网上下载大图像时,imageWithData非常有用。

我不会使用imagenamed,如果你的应用程序有不同的大图像加载。 由于使用太多,我遇到了应用程序崩溃。

我不相信图像会被caching,我不知道你为什么这么说。 UIImage是NSObject的一个子类,它使用引用计数器来跟踪它所关联的事物。 所以当你加载一个图像时,它会做同样的事情。 如果多次加载相同的图像,它将(或应该)在内存中只有一个图像副本,每次必须使用该图像的某些东西时,只需增加引用计数器。 通过参考计数器我的意思是,当计数到0时,它自己删除。 所以“alloc”,“retain”分别是count的+1和“release”是-1。 这不仅是pipe理内存的一种更好的方式,而且这种编程风格也有助于清理内存泄漏。