Associated Object Support for Swift 3.x
Of course in Swift 3, this is all trivial... but plus, if you're not using self, why bother? (Credit to this Swift 2.x example)
extension NSObject {
func setAssociated(value: T, associativeKey: UnsafeRawPointer, policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
objc_setAssociatedObject(self, associativeKey, value, policy)
}
func getAssociated(associativeKey: UnsafeRawPointer) -> T? {
let value = objc_getAssociatedObject(self, associativeKey)
return value as? T
}
}
extension UIView {
private struct AssociatedKeys {
static var viewExtension = "viewExtension"
static var anotherView = "someOtherView"
static var someFloat = "someFloat"
}
var someFloat: Float {
get {
return getAssociated(associativeKey: &AssociatedKeys.someFloat) ?? 0.0
}
set {
setAssociated(value: newValue, associativeKey: &AssociatedKeys.someFloat)
}
}
var baseTransform: CGAffineTransform? {
get {
return getAssociated(associativeKey: &AssociatedKeys.viewExtension)
}
set {
setAssociated(value: newValue, associativeKey: &AssociatedKeys.viewExtension)
}
}
var anotherView: UIView? {
get {
return getAssociated(associativeKey: &AssociatedKeys.anotherView)
}
set {
setAssociated(value: newValue, associativeKey: &AssociatedKeys.anotherView)
}
}
}
var view = UIView()
view.baseTransform = CGAffineTransform.identity
print("what's up \(view.baseTransform)")
view.baseTransform = nil
print("what's up \(view.baseTransform == nil)")
view.anotherView = UIView()
print("you got another view? \(view.anotherView) \(view.anotherView?.anotherView)")
view.anotherView = nil
view.someFloat = 32.5
print("what's it? \(view.someFloat)")
My own notes: you cannot get proper weak object support with Associated Objects, so only use them if you do not extend the actual class yourself.
Later Note
That's really not true: by wrapping your object in a Weak wrapping object, you can always get weak object support. So that's quite cool.