Ver Fonte

Fix queue issues in session delegate

onevcat há 6 anos atrás
pai
commit
33efc164ff

+ 14 - 6
Sources/Networking/ImagePrefetcher.swift

@@ -69,7 +69,11 @@ public typealias PrefetcherSourceCompletionHandler =
 /// This is useful when you know a list of image resources and want to download them before showing. It also works with
 /// some Cocoa prefetching mechanism like table view or collection view `prefetchDataSource`, to start image downloading
 /// and caching before they display on screen.
-public class ImagePrefetcher {
+public class ImagePrefetcher: CustomStringConvertible {
+
+    public var description: String {
+        return "\(Unmanaged.passUnretained(self).toOpaque())"
+    }
     
     /// The maximum concurrent downloads to use when prefetching images. Default is 5.
     public var maxConcurrentDownloads = 5
@@ -96,6 +100,7 @@ public class ImagePrefetcher {
     private let manager: KingfisherManager
 
     private let pretchQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImagePrefetcher.pretchQueue")
+    private static let requestingQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImagePrefetcher.requestingQueue")
 
     private var finished: Bool {
         let totalFinished: Int = failedSources.count + skippedSources.count + completedSources.count
@@ -259,11 +264,14 @@ public class ImagePrefetcher {
             }
         }
 
-        let downloadTask = manager.loadAndCacheImage(
-            source: source,
-            options: optionsInfo,
-            completionHandler: downloadTaskCompletionHandler)
-        
+        var downloadTask: DownloadTask.WrappedTask?
+        ImagePrefetcher.requestingQueue.sync {
+            downloadTask = manager.loadAndCacheImage(
+                source: source,
+                options: optionsInfo,
+                completionHandler: downloadTaskCompletionHandler)
+        }
+
         if let downloadTask = downloadTask {
             tasks[source.cacheKey] = downloadTask
         }

+ 4 - 2
Sources/Networking/SessionDataTask.swift

@@ -47,8 +47,10 @@ public class SessionDataTask {
     public let task: URLSessionDataTask
     private var callbacksStore = [CancelToken: TaskCallback]()
 
-    var callbacks: Dictionary<SessionDataTask.CancelToken, SessionDataTask.TaskCallback>.Values {
-        return callbacksStore.values
+    var callbacks: [SessionDataTask.TaskCallback] {
+        lock.lock()
+        defer { lock.unlock() }
+        return Array(callbacksStore.values)
     }
 
     private var currentToken = 0

+ 1 - 1
Sources/Networking/SessionDelegate.swift

@@ -248,6 +248,6 @@ extension SessionDelegate: URLSessionDataDelegate {
             return
         }
         remove(task)
-        sessionTask.onTaskDone.call((result, Array(sessionTask.callbacks)))
+        sessionTask.onTaskDone.call((result, sessionTask.callbacks))
     }
 }

+ 3 - 3
Tests/KingfisherTests/ImagePrefetcherTests.swift

@@ -252,7 +252,7 @@ class ImagePrefetcherTests: XCTestCase {
         let cache = KingfisherManager.shared.cache
         let key = testKeys[0]
 
-        cache.store(testImage, forKey: key, callbackQueue: .mainAsync) { result in
+        cache.store(testImage, forKey: key) { result in
             try! cache.memoryStorage.remove(forKey: key)
             
             XCTAssertEqual(cache.imageCachedType(forKey: key), .disk)
@@ -307,12 +307,12 @@ class ImagePrefetcherTests: XCTestCase {
             group.enter()
             let prefetcher = ImagePrefetcher(
                 resources: testURLs,
-                options: [.waitForCache])
+                options: [.cacheMemoryOnly])
             { _, _, _ in group.leave() }
             prefetcher.start()
         }
         group.notify(queue: .main) { exp.fulfill() }
-        waitForExpectations(timeout: 3, handler: nil)
+        waitForExpectations(timeout: 5, handler: nil)
     }
 
     func testPrefetchSources() {