为了账号安全,请及时绑定邮箱和手机立即绑定

[UIImage imageNamed…]和[UIImage imageWithData…]

[UIImage imageNamed…]和[UIImage imageWithData…]

iOS
森栏 2019-12-12 13:51:54
我想从文件系统将一些图像加载到我的应用程序中。有两种简单的方法可以做到这一点:[UIImage imageNamed:fullFileName]要么:NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];[UIImage imageWithData:imageData];我喜欢第一个,因为它的代码少得多,但是我看到有人说图像被缓存了,并且这种方法使用了更多的内存?由于我不信任其他大多数论坛上的人,因此我想在这里问这个问题,在实际上是否有区别,如果可以,那么哪个更好?我尝试使用对象分配工具对应用程序进行性能分析,尽管我只是在模拟器中进行了尝试,而没有在iPhone本身上进行过尝试,但我看不出任何实际的区别。
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

这取决于您对图像的处理方式。该imageNamed:方法确实缓存了图像,但是在许多情况下将有助于内存使用。例如,如果您加载一张图像10次以在表视图中与某些文本一起显示,则UIImage将仅在内存中保留该图像的单个表示,而不分配10个单独的对象。另一方面,如果图像很大,并且您不打算重新使用它,则可能要从数据对象加载图像,以确保完成后从内存中将其删除。

如果您没有任何大图像,那我就不用担心。除非您遇到问题(并且为了检查对象分配而不是先发制人地优化),否则我会选择较少的代码行,而忽略可以忽略的内存改进。


查看完整回答
反对 回复 2019-12-12
?
ibeautiful

TA贡献1993条经验 获得超5个赞

正如UIImage的API参考所说:


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


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


+(UIImage *)imageWithContentsOfFile:(NSString *)路径


此方法不缓存图像对象。


因此,我们可以看到,如果您有很多相同的UI元素(例如UITableViewCell)可能使用相同的图像(通常作为图标使用),并且由于性能原因,我们当然想重用同一图像,这样我们将为其他用途节省一些内存。通常,重用的图像通常在ui元素中使用,我们的用户可能会对其进行很多次操作。因此它对于我们重用它很有价值。因此,您可以选择使用imageNamed方法。


另一方面,在应用程序中,在应用程序的生命周期中将存在一些UI元素,例如Button,徽标视图,因此这些ui元素使用的这些图像也可能在应用程序的过程中存在。在生命周期中,您无需考虑是否应缓存这些图像。因此,您可以选择使用imageNamed方法。


相反,在应用程序中,通常会动态创建一些UI元素。例如,我们的应用程序支持动态背景,以便用户可以选择自己喜欢的背景。并且背景可以是图像。因此,我们可能有一个界面,其中列出了许多不同的背景(通常使用UIImageView进行显示)供用户选择,我们可以将列表视图命名为MyBackgroundListView。因此,一旦用户选择了背景图片,则MyBackgroundListView应该被销毁,因为它已完成其功能。下次用户想要更改其背景时,我们可以创建再次使用MyBackgroundListView。因此,不应缓存MyBackgroundListView使用的图像,否则我们的应用程序的内存将用完。因此,这一次您应该使用 imageWithContentsOfFile方法。


正如苹果公司支持Views中高分辨率屏幕的文档所说


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


因此您会担心图像的搜索路径是否存在视网膜屏幕问题。IOS将帮助您处理它。


对不起,我英语不好。可能会有所帮助。


查看完整回答
反对 回复 2019-12-12
?
萧十郎

TA贡献1815条经验 获得超12个赞

如果您不希望图像被缓存,也可以直接使用initWithContentsOfFile:


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

UIImage* yourImage = [[[UIImage alloc] initWithContentsOfFile:imagePath] autorelease];


查看完整回答
反对 回复 2019-12-12
  • 3 回答
  • 0 关注
  • 664 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信