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

+ 3 - 3
Sources/General/KFOptionsSetter.swift

@@ -436,7 +436,7 @@ extension KFOptionSetter {
     /// This is your last opportunity to modify the image download request. You can use this for customization purposes,
     /// such as adding an authentication token to the header, implementing basic HTTP authentication, or URL mapping.
     ///
-    public func requestModifier(_ modifyBlock: @escaping (inout URLRequest) -> Void) -> Self {
+    public func requestModifier(_ modifyBlock: @escaping @Sendable (inout URLRequest) -> Void) -> Self {
         options.requestModifier = AnyModifier { r -> URLRequest? in
             var request = r
             modifyBlock(&request)
@@ -474,7 +474,7 @@ extension KFOptionSetter {
     /// authentication, or URL mapping. By default, the original redirection request will be sent without any
     /// modification.
     ///
-    public func redirectHandler(_ block: @escaping (KF.RedirectPayload) -> Void) -> Self {
+    public func redirectHandler(_ block: @escaping @Sendable (KF.RedirectPayload) -> Void) -> Self {
         let redirectHandler = AnyRedirectHandler { (task, response, request, handler) in
             let payload = KF.RedirectPayload(
                 task: task, response: response, newRequest: request, completionHandler: handler
@@ -725,7 +725,7 @@ extension KFOptionSetter {
     /// - Parameter block: The block used to modify the image object.
     /// - Returns: A `Self` value with the changes applied.
     ///
-    public func imageModifier(_ block: @escaping (inout KFCrossPlatformImage) throws -> Void) -> Self {
+    public func imageModifier(_ block: @escaping @Sendable (inout KFCrossPlatformImage) throws -> Void) -> Self {
         let modifier = AnyImageModifier { image -> KFCrossPlatformImage in
             var image = image
             try block(&image)

+ 9 - 2
Sources/General/KingfisherOptionsInfo.swift

@@ -464,9 +464,16 @@ protocol DataReceivingSideEffect: AnyObject {
     func onDataReceived(_ session: URLSession, task: SessionDataTask, data: Data)
 }
 
-class ImageLoadingProgressSideEffect: DataReceivingSideEffect {
+class ImageLoadingProgressSideEffect: DataReceivingSideEffect, @unchecked Sendable {
 
-    var onShouldApply: () -> Bool = { return true }
+    private let propertyQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageLoadingProgressSideEffectPropertyQueue")
+    
+    private var _onShouldApply: () -> Bool = { return true }
+    
+    var onShouldApply: () -> Bool {
+        get { propertyQueue.sync { _onShouldApply } }
+        set { propertyQueue.sync { _onShouldApply = newValue } }
+    }
     
     let block: DownloadProgressBlock
 

+ 12 - 5
Sources/Image/ImageProgressive.swift

@@ -109,9 +109,16 @@ public struct ImageProgressive: Sendable {
 
 // A data receiving provider to update the image. Working with an `ImageProgressive`, it helps to implement the image
 // progressive effect.
-final class ImageProgressiveProvider: DataReceivingSideEffect {
+final class ImageProgressiveProvider: DataReceivingSideEffect, @unchecked Sendable {
     
-    var onShouldApply: () -> Bool = { return true }
+    private let propertyQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageProgressiveProviderPropertyQueue")
+    
+    private var _onShouldApply: () -> Bool = { return true }
+    
+    var onShouldApply: () -> Bool {
+        get { propertyQueue.sync { _onShouldApply } }
+        set { propertyQueue.sync { _onShouldApply = newValue } }
+    }
     
     func onDataReceived(_ session: URLSession, task: SessionDataTask, data: Data) {
 
@@ -310,8 +317,8 @@ private final class ImageProgressiveDecoder {
     }
 }
 
-private final class ImageProgressiveSerialQueue {
-    typealias ClosureCallback = ((@escaping () -> Void)) -> Void
+private final class ImageProgressiveSerialQueue: @unchecked Sendable {
+    typealias ClosureCallback = @Sendable ((@escaping () -> Void)) -> Void
     
     private let queue: DispatchQueue
     private var items: [DispatchWorkItem] = []
@@ -323,7 +330,7 @@ private final class ImageProgressiveSerialQueue {
     }
     
     func add(minimum interval: TimeInterval, closure: @escaping ClosureCallback) {
-        let completion = { [weak self] in
+        let completion = { @Sendable [weak self] in
             guard let self = self else { return }
             
             self.queue.async { [weak self] in