It uses a generic for the cached values itself like this:
class Cached<T> {
// The cache itself
private var cached: T?
// The closure that will provide the value when necessary
private var function: (() -> T)?
// Designated initializer
init(function: () -> T ) {
self.function = function
}
// A kludge, to allow closures to use "self".
init() {}
// Accessor
func value() -> T {
if cached == nil {
cached = function!()
}
return cached!
}
// Reset of the cached value
func invalidate() {
cached = nil
}
}
class Square {
// The cached value depends on changes to this property
var sidelength: Double = 0 {
didSet {
cachedArea.invalidate()
}
}
// A getter for the cached property
var area: Double {
get {
return cachedArea.value()
}
}
// The initialiser must specify the closures
used to calculate the cached values.
init() {
cachedArea = Cached(function: {
[unowned self] in return self.calculateArea()
} )
}
// The cached value itself is private to hide its true nature.
private var cachedArea = Cached<Double>()
// A function is used to calculate the cached value,
this keeps the initialiser readable.
private func calculateArea() -> Double {
return sidelength * sidelength
}
}
2015.05.04: Addendum, to invalidate a cache, always try to use property observers. I.e the 'didSet' and 'willSet' observers.
Happy coding...
Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH
We don't get the world we wish for... we get the world we pay for.
Seems a little verbose.
ReplyDeletevar sidelength: Double = 0 {
didSet {
_area = nil
}
}
private var _area: Double? = nil
var area: Double {
get {
return _area ?? areaValue()
}
}
func areaValue() -> Double {
let v = sidelength * sidelength
_area = v
return v
}
That is certainly possible. At the time I needed more external control to invalidate/initialize the cache. Using an explicit type with invalidate operator made the code all that much more understandable.
ReplyDelete