Associated Objects in Swift

Associated Objects in Swift

Associated objects still prove to be useful in Swift, but burdened with quite a lot of boilerplate. Fortunately it can be factored out to a helper class:

public final class ObjectAssociation<T: AnyObject> {
    
    private let policy: objc_AssociationPolicy
    
    /// - Parameter policy: An association policy that will be used when linking objects.
    public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
        
        self.policy = policy
    }
    
    /// Accesses associated object.
    /// - Parameter index: An object whose associated object is to be accessed.
    public subscript(index: AnyObject) -> T? {
        
        get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
        set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
    }
}

In result we receive succinct and readable piece of code.

extension SomeType {

    private static let association = ObjectAssociation<NSObject>()
    
    var simulatedProperty: NSObject? {

        get { return SomeType.association[self] }
        set { SomeType.association[self] = newValue }
    }
}