Browse Source

Mark manager class sendable

onevcat 1 year ago
parent
commit
27211861be

+ 17 - 5
Sources/General/KingfisherManager.swift

@@ -104,26 +104,38 @@ public typealias DownloadTaskUpdatedBlock = ((_ newTask: DownloadTask?) -> Void)
 /// methods for working with Kingfisher tasks.
 ///
 /// You can utilize this class to retrieve an image via a specified URL from the web or cache.
-public class KingfisherManager {
+public class KingfisherManager: @unchecked Sendable {
 
+    private let propertyQueue = DispatchQueue(label: "com.onevcat.Kingfisher.KingfisherManagerPropertyQueue")
+    
     /// Represents a shared manager used across Kingfisher.
     /// Use this instance for getting or storing images with Kingfisher.
     public static let shared = KingfisherManager()
 
     // Mark: Public Properties
     
+    private var _cache: ImageCache
+    
     /// The ``ImageCache`` utilized by this manager, which defaults to ``ImageCache/default``.
     ///
     /// If a cache is specified in ``KingfisherManager/defaultOptions`` or ``KingfisherOptionsInfoItem/targetCache(_:)``,
     /// those specified values will take precedence when Kingfisher attempts to retrieve or store images in the cache.
-    public var cache: ImageCache
+    public var cache: ImageCache {
+        get { propertyQueue.sync { _cache } }
+        set { propertyQueue.sync { _cache = newValue } }
+    }
+    
+    private var _downloader: ImageDownloader
     
     /// The ``ImageDownloader`` utilized by this manager, which defaults to ``ImageDownloader/default``.
     ///
     /// If a downloader is specified in ``KingfisherManager/defaultOptions`` or ``KingfisherOptionsInfoItem/downloader(_:)``,
     /// those specified values will take precedence when Kingfisher attempts to download the image data from a remote
     /// server.
-    public var downloader: ImageDownloader
+    public var downloader: ImageDownloader {
+        get { propertyQueue.sync { _downloader } }
+        set { propertyQueue.sync { _downloader = newValue } }
+    }
     
     /// The default options used by the ``KingfisherManager`` instance.
     ///
@@ -151,8 +163,8 @@ public class KingfisherManager {
     ///   - cache: The image cache that stores images in memory and on disk.
     ///
     public init(downloader: ImageDownloader, cache: ImageCache) {
-        self.downloader = downloader
-        self.cache = cache
+        _downloader = downloader
+        _cache = cache
 
         let processQueueName = "com.onevcat.Kingfisher.KingfisherManager.processQueue.\(UUID().uuidString)"
         processingQueue = .dispatch(DispatchQueue(label: processQueueName))

+ 1 - 1
Sources/General/KingfisherOptionsInfo.swift

@@ -40,7 +40,7 @@ extension Array where Element == KingfisherOptionsInfoItem {
 }
 
 /// Represents the available option items that can be used in ``KingfisherOptionsInfo``.
-public enum KingfisherOptionsInfoItem {
+public enum KingfisherOptionsInfoItem: Sendable {
     
     /// Kingfisher will utilize the associated ``ImageCache`` object when performing related operations, such as
     /// attempting to retrieve cached images and storing downloaded images in it.

+ 8 - 4
Sources/Image/Filter.swift

@@ -35,7 +35,11 @@ import UIKit
 import CoreImage
 
 // Reuses the same CI Context for all CI drawings.
-private let ciContext = CIContext(options: nil)
+struct SendableBox<T>: @unchecked Sendable {
+    let value: T
+}
+
+private let ciContext = SendableBox(value: CIContext(options: nil))
 
 /// Represents the type of transformer method, which will be used to provide a ``Filter``.
 public typealias Transformer = (CIImage) -> CIImage?
@@ -75,7 +79,7 @@ public struct Filter {
     }
     
     /// Tint filter that applies a tint color to images.
-    public static var tint: (KFCrossPlatformColor) -> Filter = {
+    public static let tint: @Sendable (KFCrossPlatformColor) -> Filter = {
         color in
         Filter {
             input in
@@ -118,7 +122,7 @@ public struct Filter {
     }
     
     /// Color control filter that applies color control changes to images.
-    public static var colorControl: (ColorElement) -> Filter = { arg -> Filter in
+    public static let colorControl: @Sendable (ColorElement) -> Filter = { arg -> Filter in
         return Filter { input in
             let paramsColor = [kCIInputBrightnessKey: arg.brightness,
                                  kCIInputContrastKey: arg.contrast,
@@ -152,7 +156,7 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage {
             return base
         }
 
-        guard let result = ciContext.createCGImage(outputImage, from: outputImage.extent) else {
+        guard let result = ciContext.value.createCGImage(outputImage, from: outputImage.extent) else {
             assertionFailure("[Kingfisher] Can not make an tint image within context.")
             return base
         }