Browse Source

Reduce unnessary queue dispatching

onevcat 10 years ago
parent
commit
25fc8cce28

+ 5 - 5
Sources/ImageCache.swift

@@ -283,12 +283,12 @@ extension ImageCache {
             if options.backgroundDecode {
                 dispatch_async(self.processQueue, { () -> Void in
                     let result = image.kf_decodedImage(scale: options.scaleFactor)
-                    dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                    dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                         completionHandler(result, .Memory)
                     })
                 })
             } else {
-                dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                     completionHandler(image, .Memory)
                 })
             }
@@ -302,21 +302,21 @@ extension ImageCache {
                             let result = image.kf_decodedImage(scale: options.scaleFactor)
                             sSelf.storeImage(result!, forKey: key, toDisk: false, completionHandler: nil)
 
-                            dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                            dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                                 completionHandler(result, .Memory)
                                 sSelf = nil
                             })
                         })
                     } else {
                         sSelf.storeImage(image, forKey: key, toDisk: false, completionHandler: nil)
-                        dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                        dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                             completionHandler(image, .Disk)
                             sSelf = nil
                         })
                     }
                 } else {
                     // No image found from either memory or disk
-                    dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                    dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                         completionHandler(nil, nil)
                         sSelf = nil
                     })

+ 1 - 1
Sources/ImageDownloader.swift

@@ -364,7 +364,7 @@ extension ImageDownloader: NSURLSessionDataDelegate {
             self.cleanForURL(imageURL)
             
             for callbackPair in callbackPairs {
-                dispatch_async(options.callbackDispatchQueue, { () -> Void in
+                dispatch_async_safely_to_queue(options.callbackDispatchQueue, { () -> Void in
                     callbackPair.completionHander?(image: image, error: error, imageURL: imageURL, originalData: originalData)
                 })
             }

+ 38 - 37
Sources/ImageView+Kingfisher.swift

@@ -204,43 +204,44 @@ extension ImageView {
             },
             completionHandler: {[weak self] image, error, cacheType, imageURL in
                 
-                guard let sSelf = self where imageURL == sSelf.kf_webURL else {
-                    completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
-                    return
-                }
-                
-                sSelf.kf_setImageTask(nil)
-                
-                guard let image = image else {
-                    indicator?.kf_stopAnimating()
-                    completionHandler?(image: nil, error: error, cacheType: cacheType, imageURL: imageURL)
-                    return
-                }
-                
-                
-                if let transitionItem = optionsInfo?.kf_firstMatchIgnoringAssociatedValue(.Transition(.None)),
-                    case .Transition(let transition) = transitionItem where cacheType == .None {
-#if !os(OSX)
-                            UIView.transitionWithView(sSelf, duration: 0.0, options: [],
-                                animations: {
-                                    indicator?.kf_stopAnimating()
-                                },
-                                completion: { finished in
-                                    UIView.transitionWithView(sSelf, duration: transition.duration,
-                                        options: transition.animationOptions,
-                                        animations: {
-                                            transition.animations?(sSelf, image)
-                                        },
-                                        completion: { finished in
-                                            transition.completion?(finished)
-                                            completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
-                                    })
-                            })
-#endif
-                } else {
-                    indicator?.kf_stopAnimating()
-                    sSelf.image = image
-                    completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
+                dispatch_async_safely_to_main_queue {
+                    guard let sSelf = self where imageURL == sSelf.kf_webURL else {
+                        completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
+                        return
+                    }
+                    
+                    sSelf.kf_setImageTask(nil)
+                    
+                    guard let image = image else {
+                        indicator?.kf_stopAnimating()
+                        completionHandler?(image: nil, error: error, cacheType: cacheType, imageURL: imageURL)
+                        return
+                    }
+                    
+                    if let transitionItem = optionsInfo?.kf_firstMatchIgnoringAssociatedValue(.Transition(.None)),
+                        case .Transition(let transition) = transitionItem where cacheType == .None {
+                            #if !os(OSX)
+                                UIView.transitionWithView(sSelf, duration: 0.0, options: [],
+                                    animations: {
+                                        indicator?.kf_stopAnimating()
+                                    },
+                                    completion: { finished in
+                                        UIView.transitionWithView(sSelf, duration: transition.duration,
+                                            options: transition.animationOptions,
+                                            animations: {
+                                                transition.animations?(sSelf, image)
+                                            },
+                                            completion: { finished in
+                                                transition.completion?(finished)
+                                                completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
+                                        })
+                                })
+                            #endif
+                    } else {
+                        indicator?.kf_stopAnimating()
+                        sSelf.image = image
+                        completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)
+                    }
                 }
             })
         

+ 7 - 3
Sources/ThreadHelper.swift

@@ -26,11 +26,15 @@
 
 import Foundation
 
-func dispatch_async_safely_main_queue(block: ()->()) {
-    if NSThread.isMainThread() {
+func dispatch_async_safely_to_main_queue(block: ()->()) {
+    dispatch_async_safely_to_queue(dispatch_get_main_queue(), block)
+}
+
+func dispatch_async_safely_to_queue(queue: dispatch_queue_t, _ block: ()->()) {
+    if queue === dispatch_get_main_queue() && NSThread.isMainThread() {
         block()
     } else {
-        dispatch_async(dispatch_get_main_queue()) {
+        dispatch_async(queue) {
             block()
         }
     }