gpt4 book ai didi

ios - 从主线程的 Assets 目录加载图像?

转载 作者:行者123 更新时间:2023-11-29 12:17:04 25 4
gpt4 key购买 nike

我正在尝试将 Assets 目录中的图像加载到主线程之外的 UIImage 中,但似乎找不到任何方法来执行此操作。如果图像不在 Assets 目录中,我将使用 pathForResource 和 imageWithContentsOfFile:

NSString *path = [[NSBundle mainBundle] pathForResource:icon ofType:nil];
if(path) {
image = [UIImage imageWithContentsOfFile:path];
}

但 pathForResource: 不适用于 Assets 目录中的图像。有什么方法可以做到这一点而不必去主线程加载图像吗?我猜答案是否定的。

什么行不通:

  • 根据主包路径手动创建图像路径。我有多个 Assets 目录中的图片, Assets 目录可以编译成二进制形式。
  • [UIImage imageNamed:] 不是线程安全的,不能在主线程外使用。文档说它至少在 iOS 的最后几个主要版本中不是线程安全的,并且从 iOS 8 开始,当它在主线程之外使用时确实会崩溃。

我现在在做什么:

dispatch_sync(dispatch_get_main_queue(), ^{
image = [UIImage imageNamed:icon];
});

最佳答案

您似乎已经回答了自己的问题:使用 dispatch_sync 在主线程上调用 imageNamed:

Assets 目录格式不透明;你唯一的接口(interface)是 imageNamed:。它的文档说:

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 locates and loads the image data from disk or asset catalog, and then returns the resulting object. You can not assume that this method is thread safe.

这里需要在速度和安全之间进行权衡;苹果选择了速度。要允许从任何线程调用 imageNamed:,需要 (A) 同步对系统缓存的访问,增加开销或 (B) 根本不使用缓存。

由于 imageNamed: 最常用于支持 UI 的图像加载,并且 UI 工作已经绑定(bind)到主线程,因此围绕这种情况进行优化是有意义的,并将同步到不在主线程上的调用者的工作。

因此,使用 dispatch_sync 是可行的方法。如果您担心线程争用,您可以轻松缓存图像,以便后台线程仅在绝对必要时才在主线程上等待。不过,除非您通过分析确定它会对性能产生显着影响,否则我不会这样做。

请注意,如果 Apple 决定允许在后台线程上调用 imageNamed:,他们将不得不同步对其缓存的访问,从而导致性能 与将 dispatch_sync 添加到您自己的代码有很大不同。

如果您的要求是:

  • 绝对绝对不能触及主线程;和
  • 您必须绝对肯定地将您的图像包含在 Assets 目录中;

那么我能看到的唯一选择是对 Assets 目录文件格式进行逆向工程并直接从磁盘读取。如果文件格式发生变化,您的应用可能会崩溃,但幸运的是,这只会在构建时发生,因此 future 的操作系统更新应该不会破坏您的应用。

关于ios - 从主线程的 Assets 目录加载图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31754641/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com