iOS DispatchQueue在后台线程上缓存的安全性

时间:2017-04-12 02:40:49

标签: ios swift caching

我正在异步创建图像,然后更新主线程上的UI。 e.g。

imageLoadingQueue.async {

    // Creates a new image, caches it.
    let newImage = ImageManager.shared.buildImage(named: ...)

    DispatchQueue.main.async {
        view.setImage(newImage)
    }
}

但是,我担心后台线程上的操作与缓存有关。

在这种情况下,ImageManager单例负责创建所需图像及其缓存(通过共享实例上的NSCache属性)。

Q值。 buildImage(named:)方法将构建的图像缓存在“共享”的属性中是否安全?

如果不是,那么buildImage(named:)方法在主线程上执行缓存是否安全,因此:

func buildImage(named name: String) -> UIImage
{
    let newImage = ... // Do the work.

    // Cache the result on the main thread, to our property.
    DispatchQueue.main.async {
        self.imageCache[key] = 
    }

    return newImage
}

... OR

另一种可能性:从缓存中分解图像创建。我不喜欢这种人工分手,因为它让ImageManager的消费者做得更多,但会采用它更安全。

imageLoadingQueue.async {

    // Build the image. Performs no caching.
    let newImage = ImageManager.shared.buildImage(named: ...)

    DispatchQueue.main.async {

        // Cache the image now that we're on the main thread.
        ImageManager.shared.cacheImage(image, key: "foo")
        view.setImage(newImage)
    }
}

感谢任何建议。

2 个答案:

答案 0 :(得分:1)

你的问题有点开放。但是,我认为您正在寻找的答案非常简单。 NSCache documentation部分说:

  
      
  • 您可以从不同的线程添加,删除和查询缓存中的项目,而无需自行锁定缓存。
  •   

所以对于你的问题,

  

Q值。 buildImage(named :)方法是否可以安全地将构建的图像缓存在'shared'上的属性中?

是的,您可以修改任何线程上的缓存,而无需采用自己的线程安全预防措施,例如异步调度到主线程。

答案 1 :(得分:0)

这取决于您在ImageManager中使用的方法/对象的线程安全性。

例如,如果您创建 UIImage ...它们在 iOS10 中是线程安全的,但是它们不在任何旧的iOS 中:意味着在较旧的iOS中你必须在主线程中创建UIImage,否则你可能会崩溃。

如果您在使用的方法和对象上查找AppleDocs,您应该能够快速找到线程安全的引用(使用这些关键字)。