Skip to content

Instantly share code, notes, and snippets.

@amelnikov78
Created November 29, 2016 03:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save amelnikov78/9f74971b591cd837e0690208ef86849f to your computer and use it in GitHub Desktop.
Save amelnikov78/9f74971b591cd837e0690208ef86849f to your computer and use it in GitHub Desktop.
Swift extensions *can* add stored properties
/////////////////////////////////////////////////////
import Foundation
func associatedObject<ValueType: AnyObject>(
base: AnyObject,
key: UnsafePointer<UInt8>,
initialiser: () -> ValueType)
-> ValueType {
if let associated = objc_getAssociatedObject(base, key)
as? ValueType { return associated }
let associated = initialiser()
objc_setAssociatedObject(base, key, associated,
.OBJC_ASSOCIATION_RETAIN)
return associated
}
func associateObject<ValueType: AnyObject>(
base: AnyObject,
key: UnsafePointer<UInt8>,
value: ValueType) {
objc_setAssociatedObject(base, key, value,
.OBJC_ASSOCIATION_RETAIN)
}
/////////////////////////////////////////////////////
class Miller {} // Here's the class we will extend
class Cat { // Every Miller should have a Cat
var name = “Puss”
}
private var catKey: UInt8 = 0 // We still need this boilerplate
extension Miller {
var cat: Cat { // cat is *effectively* a stored property
get {
return associatedObject(self, key: &catKey)
{ return Cat() } // Set the initial value of the var
}
set { associateObject(self, key: &catKey, value: newValue) }
}
}
let grumpy = Miller()
grumpy.cat.name // shows "Puss"
grumpy.cat.name = “Hephaestos”
grumpy.cat.name // shows "Hephaestos"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment