Search code examples
swiftobjective-cassociated-object

Is there a way to set associated objects in Swift?


Coming from Objective-C you can call function objc_setAssociatedObject between 2 objects to have them maintain a reference, which can be handy if at runtime you don't want an object to be destroyed until its reference is removed also. Does Swift have anything similar to this?


Solution

  • Here is a simple but complete example derived from jckarter's answer.

    It shows how to add a new property to an existing class. It does it by defining a computed property in an extension block. The computed property is stored as an associated object:

    import ObjectiveC
    
    // Declare a global var to produce a unique address as the assoc object handle
    private var AssociatedObjectHandle: UInt8 = 0
    
    extension MyClass {
        var stringProperty:String {
            get {
                return objc_getAssociatedObject(self, &AssociatedObjectHandle) as! String
            }
            set {
                objc_setAssociatedObject(self, &AssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    

    EDIT:

    If you need to support getting the value of an uninitialized property and to avoid getting the error unexpectedly found nil while unwrapping an Optional value, you can modify the getter like this:

        get {
            return objc_getAssociatedObject(self, &AssociatedObjectHandle) as? String ?? ""
        }