Created
May 27, 2020 11:39
-
-
Save ts95/8a69e242d7aae7208c1554f4bafa935a to your computer and use it in GitHub Desktop.
Swift PropertyStore class for protocols
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
class PropertyStore<Root> { | |
private var store = [AnyHashable : Any]() | |
/// Runs the computedValue closure once and stores its result in a cache for the duration | |
/// of the property store object's lifetime. Subsequent calls to this method will return the cached value. | |
func cached<T>(_ keyPath: KeyPath<Root, T>, _ computedValue: @escaping () -> T) -> T { | |
if let storedValue = store[keyPath] as? T { | |
return storedValue | |
} | |
let value = computedValue() | |
store[keyPath] = value | |
return value | |
} | |
func clear<T>(property keyPath: KeyPath<Root, T>) { | |
store[keyPath] = nil | |
} | |
func clearAll() { | |
store.removeAll() | |
} | |
} | |
// Example usage | |
protocol HasPropertyStore { | |
var ps: PropertyStore<Self> { get } | |
} | |
protocol HasLocationCoordinate: HasPropertyStore { | |
var latitude: Double { get } | |
var longitude: Double { get } | |
var locationCoordiante: CLLocationCoordinate2D { get } | |
} | |
extension HasLocationCoordinate { | |
var locationCoordiante: CLLocationCoordinate2D { | |
ps.cached(\.locationCoordiante) { | |
.init(latitude: self.latitude, longitude: self.longitude) | |
} | |
} | |
} | |
struct PointOfInterest: Codable, HasLocationCoordinate { | |
let name: String | |
let latitude: Double | |
let longitude: Double | |
let ps = PropertyStore<PointOfInterest>() | |
enum CodingKeys: String, CodingKey { | |
case name | |
case latitude | |
case longitude | |
} | |
} | |
let poi = PointOfInterest(name: "Nationaltheatret", latitude: 59.914472, longitude: 10.734372) | |
print(poi.locationCoordiante) | |
print(poi.locationCoordiante) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Property memoization discussion: https://forums.swift.org/t/memoization-of-swift-properties/38783