Last active
November 26, 2023 00:50
-
-
Save lipka/abfff806c3e494320c7e73004e348dce to your computer and use it in GitHub Desktop.
A first-class type-safe Swift cache based on NSCache with support for value types as keys.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// Based on https://www.swiftbysundell.com/articles/caching-in-swift/ | |
final class Cache<Key: Hashable, Value> { | |
private let wrapped = NSCache<WrappedKey, Entry>() | |
func insert(_ value: Value, forKey key: Key) { | |
let entry = Entry(value: value) | |
wrapped.setObject(entry, forKey: WrappedKey(key)) | |
} | |
func value(forKey key: Key) -> Value? { | |
let entry = wrapped.object(forKey: WrappedKey(key)) | |
return entry?.value | |
} | |
func removeValue(forKey key: Key) { | |
wrapped.removeObject(forKey: WrappedKey(key)) | |
} | |
} | |
extension Cache { | |
subscript(key: Key) -> Value? { | |
get { | |
return value(forKey: key) | |
} | |
set { | |
if let value = newValue { | |
insert(value, forKey: key) | |
} else { | |
removeValue(forKey: key) | |
} | |
} | |
} | |
} | |
private extension Cache { | |
final class WrappedKey: NSObject { | |
let key: Key | |
init(_ key: Key) { self.key = key } | |
override var hash: Int { return key.hashValue } | |
override func isEqual(_ object: Any?) -> Bool { | |
guard let value = object as? WrappedKey else { | |
return false | |
} | |
return value.key == key | |
} | |
} | |
} | |
private extension Cache { | |
final class Entry { | |
let value: Value | |
init(value: Value) { | |
self.value = value | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment