Просмотр исходного кода

Fix more possible Sendable warnings

onevcat 1 год назад
Родитель
Сommit
129a6b608b

+ 19 - 16
Sources/Cache/ImageCache.swift

@@ -198,22 +198,24 @@ open class ImageCache {
         let ioQueueName = "com.onevcat.Kingfisher.ImageCache.ioQueue.\(UUID().uuidString)"
         ioQueue = DispatchQueue(label: ioQueueName)
 
-        let notifications: [(Notification.Name, Selector)]
-        #if !os(macOS) && !os(watchOS)
-        notifications = [
-            (UIApplication.didReceiveMemoryWarningNotification, #selector(clearMemoryCache)),
-            (UIApplication.willTerminateNotification, #selector(cleanExpiredDiskCache)),
-            (UIApplication.didEnterBackgroundNotification, #selector(backgroundCleanExpiredDiskCache))
-        ]
-        #elseif os(macOS)
-        notifications = [
-            (NSApplication.willResignActiveNotification, #selector(cleanExpiredDiskCache)),
-        ]
-        #else
-        notifications = []
-        #endif
-        notifications.forEach {
-            NotificationCenter.default.addObserver(self, selector: $0.1, name: $0.0, object: nil)
+        Task { @MainActor in
+            let notifications: [(Notification.Name, Selector)]
+            #if !os(macOS) && !os(watchOS)
+            notifications = [
+                (UIApplication.didReceiveMemoryWarningNotification, #selector(clearMemoryCache)),
+                (UIApplication.willTerminateNotification, #selector(cleanExpiredDiskCache)),
+                (UIApplication.didEnterBackgroundNotification, #selector(backgroundCleanExpiredDiskCache))
+            ]
+            #elseif os(macOS)
+            notifications = [
+                (NSApplication.willResignActiveNotification, #selector(cleanExpiredDiskCache)),
+            ]
+            #else
+            notifications = []
+            #endif
+            notifications.forEach {
+                NotificationCenter.default.addObserver(self, selector: $0.1, name: $0.0, object: nil)
+            }
         }
     }
     
@@ -815,6 +817,7 @@ open class ImageCache {
     ///
     /// In most cases, you should not call this method explicitly. It will be called automatically when a
     ///  `UIApplicationDidEnterBackgroundNotification` is received.
+    @MainActor
     @objc public func backgroundCleanExpiredDiskCache() {
         // if 'sharedApplication()' is unavailable, then return
         guard let sharedApplication = KingfisherWrapper<UIApplication>.shared else { return }

+ 3 - 2
Sources/Extensions/CPListItem+Kingfisher.swift

@@ -236,10 +236,11 @@ extension KingfisherWrapper where Base: CPListItem {
     }
 }
 
-private var taskIdentifierKey: Void?
-private var imageTaskKey: Void?
+@MainActor private var taskIdentifierKey: Void?
+@MainActor private var imageTaskKey: Void?
 
 // MARK: Properties
+@MainActor
 extension KingfisherWrapper where Base: CPListItem {
 
     public private(set) var taskIdentifier: Source.Identifier.Value? {

+ 6 - 5
Sources/Extensions/ImageView+Kingfisher.swift

@@ -424,12 +424,13 @@ extension KingfisherWrapper where Base: KFCrossPlatformImageView {
 }
 
 // MARK: - Associated Object
-private var taskIdentifierKey: Void?
-private var indicatorKey: Void?
-private var indicatorTypeKey: Void?
-private var placeholderKey: Void?
-private var imageTaskKey: Void?
+@MainActor private var taskIdentifierKey: Void?
+@MainActor private var indicatorKey: Void?
+@MainActor private var indicatorTypeKey: Void?
+@MainActor private var placeholderKey: Void?
+@MainActor private var imageTaskKey: Void?
 
+@MainActor
 extension KingfisherWrapper where Base: KFCrossPlatformImageView {
 
     // MARK: Properties

+ 6 - 4
Sources/Extensions/UIButton+Kingfisher.swift

@@ -340,10 +340,11 @@ extension KingfisherWrapper where Base: UIButton {
 }
 
 // MARK: - Associated Object
-private var taskIdentifierKey: Void?
-private var imageTaskKey: Void?
+@MainActor private var taskIdentifierKey: Void?
+@MainActor private var imageTaskKey: Void?
 
 // MARK: Properties
+@MainActor
 extension KingfisherWrapper where Base: UIButton {
 
     private typealias TaskIdentifier = Box<[UInt: Source.Identifier.Value]>
@@ -370,10 +371,11 @@ extension KingfisherWrapper where Base: UIButton {
 }
 
 
-private var backgroundTaskIdentifierKey: Void?
-private var backgroundImageTaskKey: Void?
+@MainActor private var backgroundTaskIdentifierKey: Void?
+@MainActor private var backgroundImageTaskKey: Void?
 
 // MARK: Background Properties
+@MainActor
 extension KingfisherWrapper where Base: UIButton {
     
     public func backgroundTaskIdentifier(for state: UIControl.State) -> Source.Identifier.Value? {

+ 1 - 1
Sources/General/ImageSource/AVAssetImageDataProvider.swift

@@ -27,7 +27,7 @@
 #if !os(watchOS)
 
 import Foundation
-import AVKit
+@preconcurrency import AVKit
 
 #if canImport(MobileCoreServices)
 import MobileCoreServices

+ 1 - 1
Sources/General/KingfisherManager.swift

@@ -84,7 +84,7 @@ public struct RetrieveImageResult: Sendable {
 
 /// A structure that stores related information about a ``KingfisherError``. It provides contextual information
 /// to facilitate the identification of the error.
-public struct PropagationError {
+public struct PropagationError: Sendable {
 
     /// The ``Source`` to which current `error` is bound.
     public let source: Source

+ 5 - 5
Sources/Image/ImageFormat.swift

@@ -27,7 +27,7 @@
 import Foundation
 
 /// Represents the image format.
-public enum ImageFormat {
+public enum ImageFormat: Sendable {
     /// The format cannot be recognized or not supported yet.
     case unknown
     /// PNG image format.
@@ -38,10 +38,10 @@ public enum ImageFormat {
     case GIF
     
     struct HeaderData {
-        static var PNG: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]
-        static var JPEG_SOI: [UInt8] = [0xFF, 0xD8]
-        static var JPEG_IF: [UInt8] = [0xFF]
-        static var GIF: [UInt8] = [0x47, 0x49, 0x46]
+        static let PNG: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]
+        static let JPEG_SOI: [UInt8] = [0xFF, 0xD8]
+        static let JPEG_IF: [UInt8] = [0xFF]
+        static let GIF: [UInt8] = [0x47, 0x49, 0x46]
     }
     
     /// JPEG marker of each sequence of segments.

+ 5 - 5
Sources/Image/ImageProcessor.swift

@@ -103,7 +103,7 @@ func !=(left: ImageProcessor, right: ImageProcessor) -> Bool {
     return !(left == right)
 }
 
-typealias ProcessorImp = ((ImageProcessItem, KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?)
+typealias ProcessorImp = (@Sendable (ImageProcessItem, KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?)
 struct GeneralProcessor: ImageProcessor {
     let identifier: String
     let p: ProcessorImp
@@ -141,7 +141,7 @@ public struct DefaultImageProcessor: ImageProcessor {
 }
 
 /// Represents the rect corner setting when processing a round corner image.
-public struct RectCorner: OptionSet {
+public struct RectCorner: OptionSet, Sendable {
     
     /// Raw value for the corner radius.
     public let rawValue: Int
@@ -279,7 +279,7 @@ public struct CompositingImageProcessor: ImageProcessor {
 #endif
 
 /// Represents a radius specified in a ``RoundCornerImageProcessor``.
-public enum Radius {
+public enum Radius: Sendable {
     
     /// The radius should be calculated as a fraction of the image width. Typically, the associated value should be
     /// between 0 and 0.5, where 0 represents no radius, and 0.5 represents using half of the image width.
@@ -431,7 +431,7 @@ public struct RoundCornerImageProcessor: ImageProcessor {
 /// Represents a border to be added to the image.
 ///
 /// Typically used with ``BorderImageProcessor``, which adds the border to the image.
-public struct Border {
+public struct Border: Sendable {
     
     /// The color of the border to create.
     public var color: KFCrossPlatformColor
@@ -498,7 +498,7 @@ public struct BorderImageProcessor: ImageProcessor {
 }
 
 /// Represents how a size of content adjusts itself to fit a target size.
-public enum ContentMode {
+public enum ContentMode: Sendable {
     /// Does not scale the content.
     case none
     /// Scales the content to fit the size of the view while maintaining the aspect ratio.

+ 1 - 0
Sources/Image/Placeholder.swift

@@ -70,6 +70,7 @@ extension KFCrossPlatformImage: Placeholder {
 ///
 /// To use your customized View type as a placeholder, simply have it conform to
 /// `Placeholder` using an extension: `extension MyView: Placeholder {}`.
+@MainActor
 extension Placeholder where Self: KFCrossPlatformView {
     
     public func add(to imageView: KFCrossPlatformImageView) {

+ 2 - 2
Sources/Networking/ImageDownloader.swift

@@ -33,7 +33,7 @@ import UIKit
 typealias DownloadResult = Result<ImageLoadingResult, KingfisherError>
 
 /// Represents a successful result of an image downloading process.
-public struct ImageLoadingResult {
+public struct ImageLoadingResult: Sendable {
 
     /// The downloaded image.
     public let image: KFCrossPlatformImage
@@ -62,7 +62,7 @@ public struct ImageLoadingResult {
 /// When a download starts in Kingfisher, the involved methods always return you an instance of ``DownloadTask``. If you
 /// need to cancel the task during the download process, you can keep a reference to the instance and call ``cancel()``
 /// on it.
-public class DownloadTask {
+public final class DownloadTask: Sendable {
     
     init(sessionTask: SessionDataTask, cancelToken: SessionDataTask.CancelToken) {
         self.sessionTask = sessionTask

+ 1 - 1
Sources/Utility/CallbackQueue.swift

@@ -29,7 +29,7 @@ import Foundation
 public typealias ExecutionQueue = CallbackQueue
 
 /// Represents the behavior of the callback queue selection when a closure is dispatched.
-public enum CallbackQueue {
+public enum CallbackQueue: Sendable {
     
     /// Dispatches the closure to `DispatchQueue.main` with an `async` behavior.
     case mainAsync

+ 2 - 0
Sources/Views/Indicator.swift

@@ -53,6 +53,7 @@ public enum IndicatorType {
 }
 
 /// An indicator type which can be used to show that the download task is in progress.
+@MainActor 
 public protocol Indicator {
     
     /// Called when the indicator should start animating.
@@ -106,6 +107,7 @@ extension Indicator {
 }
 
 // Displays a NSProgressIndicator / UIActivityIndicatorView
+@MainActor
 final class ActivityIndicator: Indicator {
 
     #if os(macOS)