onevcat пре 11 година
родитељ
комит
f2c1c878f7

+ 39 - 13
Kingfisher/ImageCache.swift

@@ -10,7 +10,8 @@ import Foundation
 
 private let defaultCacheName = "default"
 private let cacheReverseDNS = "com.onevcat.Kingfisher.ImageCache."
-private let ioQueneName = "com.onevcat.Kingfisher.ImageCache.ioQueue"
+private let ioQueueName = "com.onevcat.Kingfisher.ImageCache.ioQueue"
+private let processQueueName = "com.onevcat.Kingfisher.ImageCache.processQueue"
 
 private let defaultCacheInstance = ImageCache(name: defaultCacheName)
 private let defaultMaxCachePeriodInSecond: NSTimeInterval = 60 * 60 * 24 * 7 //Cache exists for 1 week
@@ -36,10 +37,12 @@ public class ImageCache {
     private let memoryCache = NSCache()
     
     //Disk
-    private let ioQueue = dispatch_queue_create(ioQueneName, DISPATCH_QUEUE_SERIAL)
+    private let ioQueue = dispatch_queue_create(ioQueueName, DISPATCH_QUEUE_SERIAL)
     private let diskCachePath: String
     private var fileManager: NSFileManager!
     
+    private let processQueue = dispatch_queue_create(processQueueName, DISPATCH_QUEUE_CONCURRENT)
+    
     public class var defaultCache: ImageCache {
         return defaultCacheInstance
     }
@@ -132,7 +135,7 @@ public extension ImageCache {
 
 // MARK: - Get data from cache
 extension ImageCache {
-    public func retrieveImageForKey(key: String, completionHandler: ((UIImage?, CacheType!) -> ())?) -> RetrieveImageDiskTask? {
+    public func retrieveImageForKey(key: String, options:KingfisherManager.Options, completionHandler: ((UIImage?, CacheType!) -> ())?) -> RetrieveImageDiskTask? {
         // No completion handler. Not start working and early return.
         if (completionHandler == nil) {
             return dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS) {}
@@ -140,20 +143,43 @@ extension ImageCache {
         
         let block = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS) {
             if let image = self.retriveImageInMemoryCaheForKey(key) {
+                
                 //Found image in memory cache.
-                completionHandler?(image, .Memory)
+                if options.shouldDecode {
+                    dispatch_async(self.processQueue, { () -> Void in
+                        let result = image.kf_decodedImage()
+                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
+                            completionHandler?(result, .Memory)
+                            return
+                        })
+                    })
+                } else {
+                    completionHandler?(image, .Memory)
+                }
             } else {
                 //Begin to load image from disk
                 dispatch_async(self.ioQueue, { () -> Void in
                     
                     if let image = self.retriveImageInDiskCacheForKey(key) {
-                        self.storeImage(image, forKey: key, toDisk: false, completionHandler: nil)
-                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
-                            if let completionHandler = completionHandler {
-                                completionHandler(image, .Disk)
-                            }
-                        })
                         
+                        if options.shouldDecode {
+                            dispatch_async(self.processQueue, { () -> Void in
+                                let result = image.kf_decodedImage()
+                                self.storeImage(result!, forKey: key, toDisk: false, completionHandler: nil)
+                                
+                                dispatch_async(dispatch_get_main_queue(), { () -> Void in
+                                    completionHandler?(result, .Memory)
+                                    return
+                                })
+                            })
+                        } else {
+                            self.storeImage(image, forKey: key, toDisk: false, completionHandler: nil)
+                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
+                                if let completionHandler = completionHandler {
+                                    completionHandler(image, .Disk)
+                                }
+                            })
+                        }
                     } else {
                         // No image found from either memory or disk
                         dispatch_async(dispatch_get_main_queue(), { () -> Void in
@@ -223,7 +249,7 @@ extension ImageCache {
                     options: NSDirectoryEnumerationOptions.SkipsHiddenFiles,
                     errorHandler: nil) {
                         
-                    for fileURL in fileEnumerator.allObjects as [NSURL] {
+                    for fileURL in fileEnumerator.allObjects as! [NSURL] {
                             
                         if let resourceValues = fileURL.resourceValuesForKeys(resourceKeys, error: nil) {
                             // If it is a Directory. Continue to next file URL.
@@ -242,7 +268,7 @@ extension ImageCache {
                             }
                             
                             if let fileSize = resourceValues[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
-                                diskCacheSize += fileSize.unsignedIntegerValue
+                                diskCacheSize += fileSize.unsignedLongValue
                                 cachedFiles[fileURL] = resourceValues
                             }
                         }
@@ -272,7 +298,7 @@ extension ImageCache {
                     for fileURL in sortedFiles {
                         if (self.fileManager.removeItemAtURL(fileURL, error: nil)) {
                             if let fileSize = cachedFiles[fileURL]?[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
-                                diskCacheSize -= fileSize.unsignedIntegerValue
+                                diskCacheSize -= fileSize.unsignedLongValue
                             }
                             
                             if diskCacheSize < targetSize {

+ 3 - 7
Kingfisher/ImageDownloader.swift

@@ -101,9 +101,7 @@ extension ImageDownloader: NSURLSessionDataDelegate {
     
     public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
         
-        let url = dataTask.originalRequest.URL
-        
-        if let callbackPairs = fetchLoads[url]?.callbacks {
+        if let url = dataTask.originalRequest.URL, callbackPairs = fetchLoads[url]?.callbacks {
             for callbackPair in callbackPairs {
                 callbackPair.progressBlock?(receivedSize: 0, totalSize: response.expectedContentLength)
             }
@@ -113,9 +111,7 @@ extension ImageDownloader: NSURLSessionDataDelegate {
     
     public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
 
-        let url = dataTask.originalRequest.URL
-
-        if let fetchLoad = fetchLoads[url] {
+        if let url = dataTask.originalRequest.URL, fetchLoad = fetchLoads[url] {
             fetchLoad.responsData.appendData(data)
             for callbackPair in fetchLoad.callbacks {
                 callbackPair.progressBlock?(receivedSize: Int64(fetchLoad.responsData.length), totalSize: dataTask.response!.expectedContentLength)
@@ -135,7 +131,7 @@ extension ImageDownloader: NSURLSessionDataDelegate {
     
     public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
         
-        let url = task.originalRequest.URL
+        let url = task.originalRequest.URL!
         
         if let error = error { // Error happened
             callbackWithImage(nil, error: error, imageURL: url)

+ 1 - 1
Kingfisher/KingfisherManager.swift

@@ -70,7 +70,7 @@ public class KingfisherManager {
                     completionHandler: completionHandler,
                     options: options)
             } else {
-                let diskTask = cache.retrieveImageForKey(key, completionHandler: { (image, cacheType) -> () in
+                let diskTask = cache.retrieveImageForKey(key, options: options, completionHandler: { (image, cacheType) -> () in
                     if image != nil {
                         completionHandler?(image: image, error: nil, imageURL: url)
                     } else {

+ 21 - 16
Kingfisher/String+MD5.swift

@@ -46,15 +46,15 @@ extension String {
 }
 
 /** array of bytes, little-endian representation */
-func arrayOfBytes<T>(value:T, length:Int? = nil) -> [Byte] {
+func arrayOfBytes<T>(value:T, length:Int? = nil) -> [UInt8] {
     let totalBytes = length ?? (sizeofValue(value) * 8)
     var v = value
     
     var valuePointer = UnsafeMutablePointer<T>.alloc(1)
     valuePointer.memory = value
     
-    var bytesPointer = UnsafeMutablePointer<Byte>(valuePointer)
-    var bytes = [Byte](count: totalBytes, repeatedValue: 0)
+    var bytesPointer = UnsafeMutablePointer<UInt8>(valuePointer)
+    var bytes = [UInt8](count: totalBytes, repeatedValue: 0)
     for j in 0..<min(sizeof(T),totalBytes) {
         bytes[totalBytes - 1 - j] = (bytesPointer + j).memory
     }
@@ -67,7 +67,7 @@ func arrayOfBytes<T>(value:T, length:Int? = nil) -> [Byte] {
 
 extension Int {
     /** Array of bytes with optional padding (little-endian) */
-    public func bytes(_ totalBytes: Int = sizeof(Int)) -> [Byte] {
+    public func bytes(_ totalBytes: Int = sizeof(Int)) -> [UInt8] {
         return arrayOfBytes(self, length: totalBytes)
     }
     
@@ -76,7 +76,7 @@ extension Int {
 extension NSMutableData {
     
     /** Convenient way to append bytes */
-    internal func appendBytes(arrayOfBytes: [Byte]) {
+    internal func appendBytes(arrayOfBytes: [UInt8]) {
         self.appendBytes(arrayOfBytes, length: arrayOfBytes.count)
     }
     
@@ -95,12 +95,17 @@ class HashBase {
         var tmpMessage: NSMutableData = NSMutableData(data: self.message)
         
         // Step 1. Append Padding Bits
-        tmpMessage.appendBytes([0x80]) // append one bit (Byte with one bit) to message
+        tmpMessage.appendBytes([0x80]) // append one bit (UInt8 with one bit) to message
         
         // append "0" bit until message length in bits ≡ 448 (mod 512)
-        while tmpMessage.length % len != (len - 8) {
-            tmpMessage.appendBytes([0x00])
+        var msgLength = tmpMessage.length;
+        var counter = 0;
+        while msgLength % len != (len - 8) {
+            counter++
+            msgLength++
         }
+        var bufZeros = UnsafeMutablePointer<UInt8>(calloc(counter, sizeof(UInt8)))
+        tmpMessage.appendBytes(bufZeros, length: counter)
         
         return tmpMessage
     }
@@ -147,19 +152,19 @@ class MD5 : HashBase {
         // Step 2. Append Length a 64-bit representation of lengthInBits
         var lengthInBits = (message.length * 8)
         var lengthBytes = lengthInBits.bytes(64 / 8)
-        tmpMessage.appendBytes(reverse(lengthBytes))
+        tmpMessage.appendBytes(reverse(lengthBytes));
         
         // Process the message in successive 512-bit chunks:
         let chunkSizeBytes = 512 / 8 // 64
         var leftMessageBytes = tmpMessage.length
-        for var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes {
+        for (var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes) {
             let chunk = tmpMessage.subdataWithRange(NSRange(location: i, length: min(chunkSizeBytes,leftMessageBytes)))
+            let bytes = tmpMessage.bytes;
             
             // break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
             var M:[UInt32] = [UInt32](count: 16, repeatedValue: 0)
-            for x in 0..<M.count {
-                chunk.getBytes(&M[x], range:NSRange(location:x * sizeofValue(M[x]), length: sizeofValue(M[x])))
-            }
+            let range = NSRange(location:0, length: M.count * sizeof(UInt32))
+            chunk.getBytes(UnsafeMutablePointer<Void>(M), range: range)
             
             // Initialize hash value for this chunk:
             var A:UInt32 = hh[0]
@@ -207,12 +212,12 @@ class MD5 : HashBase {
             hh[3] = hh[3] &+ D
         }
         
-        var buf: NSMutableData = NSMutableData()
+        var buf: NSMutableData = NSMutableData();
         hh.map({ (item) -> () in
             var i:UInt32 = item.littleEndian
             buf.appendBytes(&i, length: sizeofValue(i))
         })
         
-        return buf.copy() as NSData
+        return buf.copy() as! NSData;
     }
-}
+}