Skip to content

Instantly share code, notes, and snippets.

@aleclarson
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aleclarson/e7d359b6dd466e3eac8b to your computer and use it in GitHub Desktop.
Save aleclarson/e7d359b6dd466e3eac8b to your computer and use it in GitHub Desktop.
Associated
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