【问题标题】:what is the advantage of imageNamed?imageNamed 的优势是什么?
【发布时间】:2015-03-05 21:23:19
【问题描述】:

我知道加载这样的图像

  UIImage *image = [UIImage imageNamed:@"img"];

将缓存图像并不会像这样加载它

  UIImage *image = [UIImage imageWithContentsOfFile:@"img.png"];

人们说访问缓存的图像会更快,因为 iOS 会从内存中访问它,我们不会有读取和解码文件的开销。好的,我明白了,但是假设我使用第二种非缓存方法将图像加载到作为属性的视图上,就像这样

  UIImage *image = [UIImage imageWithContentsOfFile:@"img.png"];
  self.imageView = [[UIImageView alloc] initWithImage:image];

图像不是已经在内存中了吗?如果我想访问它,我只需执行 imageView.image 并从内存中获取它。

我可能很累,但我无法想象缓存版本的单一用途,或者我不明白这个缓存的含义。

愿意解释一下吗?谢谢。

【问题讨论】:

  • 缓存和内存是两个不同的概念。比如说,当你使用 imageNamed 时,它会首先在缓存中查找,如果它在那里,它将被加载,否则将从磁盘加载。当您使用 imageWithContentsOfFile 时:它会直接从磁盘加载图像。
  • 想想如果你的imageView在firstView上并且你正在调用imageWithContentsOfFile,它如何访问第一个视图的imageView并获取图像?
  • 如果您只在没有从imageNamed: 获得任何好处时访问/加载图像,实际上在这种情况下您应该使用imageWithContentsOfFile:,使用imageNamed: 的好处是当您使用相同的来自多个地方的图片
  • 如果您在应用运行期间多次需要该图像,则使用缓存...
  • 那么,您的意思是,如果图像被缓存,我只能将图像保存到属性中?我不这么认为。

标签: ios cocoa-touch caching uiimage


【解决方案1】:

假设您的图像是您在 7 个不同的视图控制器中使用的某个图标...您可以加载图像一次然后将其传递给每个 VC,或者您可以使用imageNamed...您的选择。

【讨论】:

  • 你的解释不好。即使没有缓存,我也可以将图像传递给另一个 viewController。
  • 我在解释中说过。你可以这样做,但你不必这样做,因为你可以改用imageNamed
  • 啊,我明白了。缓存是一个带有图像和标签的盒子,它不附加任何东西。谢谢
【解决方案2】:

来自the documentation

此方法在系统缓存中查找具有指定名称的图像对象,如果存在则返回该对象。如果匹配的图像对象尚未在缓存中,则此方法从磁盘或资产分类日志中定位并加载图像数据,然后返回结果对象。你不能假设这个方法是线程安全的。

假设您的应用中有一张图片。当你需要使用图像时,你使用这个代码:

UIImage *image = [UIImage imageWithContentsOfFile:@"img.png"];

然后,iOS 会在 app bundle 中查找您的图片,将其加载到内存中,然后将其解码到 UIImage 中。

但是,假设您需要 10 个不同的对象来使用图像,并且您加载它的方式类似于:

for (ClassThatNeedsImage *object in objects) {
    object.image = [UIImage imageWithContentsOfFile:@"img.png"];
}

(这不是最好的示例,因为您可以只加载一次图像并将其传递给每个对象。但是,我有更复杂的代码,这不是一个选项。)

iOS 会查找图像 10 次,将其加载到内存中 10 次,然后解码 10 次。但是,如果您使用 imageNamed:

for (ClassThatNeedsImage *object in objects) {
    object.image = [UIImage imageNamed:@"img"];
}

来自Wikipedia

在计算中,缓存是一种透明存储数据的组件,以便可以更快地处理未来对该数据的请求。

UIImage使用的缓存存储在内存中,访问速度比磁盘快很多。

第一次循环时,iOS 会在缓存中查看图像是否存储在那里。假设您之前没有使用imageNamed 加载此图像,它没有找到它,因此它会查找图像,将其加载到内存中,对其进行解码,然后将其复制到缓存中。

在其他迭代中,iOS 会在缓存中查找图像,然后将其复制到 UIImage 对象中,因此它根本不需要进行任何硬盘访问。


如果您打算在应用的生命周期内只使用一次图像,请使用imageWithContentsOfFile:。如果要多次使用该图像,请使用imageNamed:

【讨论】:

    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2017-06-21
    • 2013-05-15
    • 1970-01-01
    • 2011-07-15
    相关资源
    最近更新 更多