فهرست منبع

Replace memoryCacheExpirationNotExtendable with memoryCacheAccessExtendingExpiration(let expiration) option

Dominique Stranz 6 سال پیش
والد
کامیت
f874ef1ff5

+ 1 - 1
Sources/Cache/ImageCache.swift

@@ -525,7 +525,7 @@ open class ImageCache {
         options: KingfisherParsedOptionsInfo) -> Image?
     {
         let computedKey = key.computedKey(with: options.processor.identifier)
-        return memoryStorage.value(forKey: computedKey, extendingExpiration: options.memoryCacheReadExtendingExpiration)
+        return memoryStorage.value(forKey: computedKey, extendingExpiration: options.memoryCacheAccessExtendingExpiration)
     }
 
     /// Gets an image for a given key from the memory storage.

+ 23 - 11
Sources/Cache/MemoryStorage.swift

@@ -121,26 +121,29 @@ public enum MemoryStorage {
             storage.setObject(object, forKey: key as NSString, cost: value.cacheCost)
             keys.insert(key)
         }
-
-        // Use this when you actually access the memory cached item.
-        // This will extend the expired data for the accessed item.
-        func value(forKey key: String) throws -> T? {
-            return value(forKey: key, extendingExpiration: true)
-        }
-
-        func value(forKey key: String, extendingExpiration: Bool) -> T? {
+        
+        /// Use this when you actually access the memory cached item.
+        /// By default, this will extend the expired data for the accessed item.
+        ///
+        /// - Parameters:
+        ///   - key: Cache Key
+        ///   - extendingExpiration: expiration value to extend item expiration time:
+        ///     * .never will not extend expiration
+        ///     * nil (default value) will use object cache expiration settings
+        /// - Returns: cached object or nil
+        func value(forKey key: String, extendingExpiration: StorageExpiration? = nil) -> T? {
             guard let object = storage.object(forKey: key as NSString) else {
                 return nil
             }
             if object.expired {
                 return nil
             }
-            if extendingExpiration { object.extendExpiration() }
+            object.extendExpiration(by: extendingExpiration ?? object.expiration)
             return object.value
         }
 
         func isCached(forKey key: String) -> Bool {
-            guard let _ = value(forKey: key, extendingExpiration: false) else {
+            guard let _ = value(forKey: key, extendingExpiration: .never) else {
                 return false
             }
             return true
@@ -221,7 +224,16 @@ extension MemoryStorage {
         }
         
         func extendExpiration() {
-            self.estimatedExpiration = expiration.estimatedExpirationSinceNow
+            extendExpiration(by: expiration)
+        }
+        
+        func extendExpiration(by extendingExpiration: StorageExpiration) {
+            switch extendingExpiration {
+            case .never:
+                return
+            default:
+                self.estimatedExpiration = extendingExpiration.estimatedExpirationSinceNow
+            }
         }
         
         var expired: Bool {

+ 6 - 5
Sources/General/KingfisherOptionsInfo.swift

@@ -203,9 +203,10 @@ public enum KingfisherOptionsInfoItem {
     /// value to overwrite the config setting for this caching item.
     case memoryCacheExpiration(StorageExpiration)
     
-    /// By default, every read operation for an item is extending it's expiration time. Use this setting to
-    /// disable this behavior and expire item regardless it's next requests.
-    case memoryCacheExpirationNotExtendable
+    /// The expiration extending setting for memory cache. Item expiration time will be incremented by this value after access
+    /// By default, the underlying `MemoryStorage.Backend` uses the expiration extending in its config for all items. If set, the `MemoryStorage.Backend` will use this associated
+    /// value to overwrite the config setting for this caching item.
+    case memoryCacheAccessExtendingExpiration(StorageExpiration)
     
     /// The expiration setting for memory cache. By default, the underlying `DiskStorage.Backend` uses the
     /// expiration in its config for all items. If set, the `DiskStorage.Backend` will use this associated
@@ -256,7 +257,7 @@ public struct KingfisherParsedOptionsInfo {
     public var alsoPrefetchToMemory = false
     public var loadDiskFileSynchronously = false
     public var memoryCacheExpiration: StorageExpiration? = nil
-    public var memoryCacheReadExtendingExpiration = true
+    public var memoryCacheAccessExtendingExpiration: StorageExpiration? = nil
     public var diskCacheExpiration: StorageExpiration? = nil
     public var processingQueue: CallbackQueue? = nil
     public var progressiveJPEG: ImageProgressive? = nil
@@ -295,7 +296,7 @@ public struct KingfisherParsedOptionsInfo {
             case .loadDiskFileSynchronously: loadDiskFileSynchronously = true
             case .callbackDispatchQueue(let value): callbackQueue = value.map { .dispatch($0) } ?? .mainCurrentOrAsync
             case .memoryCacheExpiration(let expiration): memoryCacheExpiration = expiration
-            case .memoryCacheExpirationNotExtendable: memoryCacheReadExtendingExpiration = false
+            case .memoryCacheAccessExtendingExpiration(let expiration): memoryCacheAccessExtendingExpiration = expiration
             case .diskCacheExpiration(let expiration): diskCacheExpiration = expiration
             case .processingQueue(let queue): processingQueue = queue
             case .progressiveJPEG(let value): progressiveJPEG = value

+ 3 - 2
Tests/KingfisherTests/ImageViewExtensionTests.swift

@@ -658,7 +658,7 @@ class ImageViewExtensionTests: XCTestCase {
         let url = testURLs[0]
         stub(url, data: testImageData)
         
-        let options: KingfisherOptionsInfo = [.cacheMemoryOnly, .memoryCacheExpiration(.seconds(1))]
+        let options: KingfisherOptionsInfo = [.cacheMemoryOnly, .memoryCacheExpiration(.seconds(1)), .memoryCacheAccessExtendingExpiration(.seconds(100))]
        
         imageView.kf.setImage(with: url, options: options) { result in
             XCTAssertNotNil(result.value?.image)
@@ -678,6 +678,7 @@ class ImageViewExtensionTests: XCTestCase {
                     XCTAssertNotNil(expirationTime2)
                     XCTAssertNotEqual(expirationTime1, expirationTime2)
                     XCTAssert(expirationTime1!.isPast(referenceDate: expirationTime2!))
+                    XCTAssertGreaterThan(expirationTime2!.timeIntervalSince(expirationTime1!), 10)
                     
                     exp.fulfill()
                 }
@@ -692,7 +693,7 @@ class ImageViewExtensionTests: XCTestCase {
         let url = testURLs[0]
         stub(url, data: testImageData)
         
-        let options: KingfisherOptionsInfo = [.cacheMemoryOnly, .memoryCacheExpirationNotExtendable, .memoryCacheExpiration(.seconds(1))]
+        let options: KingfisherOptionsInfo = [.cacheMemoryOnly, .memoryCacheExpiration(.seconds(1)), .memoryCacheAccessExtendingExpiration(.never)]
   
         imageView.kf.setImage(with: url, options: options) { result in
             XCTAssertNotNil(result.value?.image)

+ 2 - 3
Tests/KingfisherTests/KingfisherOptionsInfoTests.swift

@@ -52,7 +52,6 @@ class KingfisherOptionsInfoTests: XCTestCase {
         XCTAssertFalse(options.keepCurrentImageWhileLoading)
         XCTAssertFalse(options.onlyLoadFirstFrame)
         XCTAssertFalse(options.cacheOriginalImage)
-        XCTAssertTrue(options.memoryCacheReadExtendingExpiration)
     }
     
     func testSetOptionsShouldParseCorrectly() {
@@ -90,7 +89,7 @@ class KingfisherOptionsInfoTests: XCTestCase {
             .keepCurrentImageWhileLoading,
             .onlyLoadFirstFrame,
             .cacheOriginalImage,
-            .memoryCacheExpirationNotExtendable
+            .memoryCacheAccessExtendingExpiration(.seconds(1))
         ])
         
         XCTAssertTrue(options.targetCache === cache)
@@ -111,7 +110,7 @@ class KingfisherOptionsInfoTests: XCTestCase {
         XCTAssertTrue(options.fromMemoryCacheOrRefresh)
         XCTAssertTrue(options.forceTransition)
         XCTAssertTrue(options.cacheMemoryOnly)
-        XCTAssertFalse(options.memoryCacheReadExtendingExpiration)
+        XCTAssertEqual(options.memoryCacheAccessExtendingExpiration?.timeInterval, 1)
         XCTAssertTrue(options.waitForCache)
         XCTAssertTrue(options.onlyFromCache)
         XCTAssertTrue(options.backgroundDecode)

+ 2 - 2
Tests/KingfisherTests/MemoryStorageTests.swift

@@ -151,7 +151,7 @@ class MemoryStorageTests: XCTestCase {
             XCTAssertNotNil(expirationDate1)
             
             // Request for the object to extend it's expiration date
-            let obj = self.storage.value(forKey: "1", extendingExpiration: true)
+            let obj = self.storage.value(forKey: "1", extendingExpiration: .seconds(5))
             XCTAssertNotNil(obj)
             
             let expirationDate2 = self.storage.storage.object(forKey: "1")?.estimatedExpiration
@@ -177,7 +177,7 @@ class MemoryStorageTests: XCTestCase {
             XCTAssertNotNil(expirationDate1)
             
             // Request for the object to extend it's expiration date
-            let obj = self.storage.value(forKey: "1", extendingExpiration: false)
+            let obj = self.storage.value(forKey: "1", extendingExpiration: .never)
             XCTAssertNotNil(obj)
             
             let expirationDate2 = self.storage.storage.object(forKey: "1")?.estimatedExpiration