Last active
August 29, 2015 14:07
-
-
Save aleclarson/e7d359b6dd466e3eac8b to your computer and use it in GitHub Desktop.
Associated
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 EmitterKit | |
/// Forces an `object` to retain the given `value` until the `object` is deallocated. | |
/// | |
/// You must retain the returned Associated<T> object in order to keep the `value` retained by the `object`. | |
/// | |
/// Alternatively, you can call `keepAlive()` on the Associated<T> to prevent the `value` from being deallocated when the Associated<T> is released. | |
/// | |
public func associate <T> (value: T, with object: AnyObject) -> Associated<T> { | |
return Associated(value, object) | |
} | |
public class Associated <T> { | |
/// The object this value is associated with. | |
public private(set) weak var object: AnyObject! | |
/// The value that is associated. | |
public var value: T! { | |
get { | |
let value: AnyObject! = _value?.object | |
return value == nil ? nil : ((value as? _Value)?.value as? T) ?? (value as T) | |
} | |
set { | |
let newValue: AnyObject! = newValue == nil ? nil : isObject(newValue) ? cast(newValue) : _Value(newValue) | |
_value = newValue == nil ? nil : AnyReference(newValue, .Weak) | |
objc_setAssociatedObject(object, objectToPointer(self), newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) | |
} | |
} | |
/// Forces the `object` to retain the `value` even after this Associated<T> is released. | |
public func keepAlive () { | |
_keepAlive = true | |
} | |
// MARK: Private | |
private var _keepAlive = false | |
private var _value: AnyReference! | |
private init (_ value: T, _ object: AnyObject) { | |
self.object = object | |
self.value = value | |
} | |
deinit { | |
if !_keepAlive { | |
value = nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment