Search code examples
swiftassociated-object

Swift objc_getAssociatedObject always nil


I am trying to associated a property to an Array Extension:

private var AssociatedObjectHandle: String = "BlaBLabla"
extension Array {
  var emptyIndex:Int {
    mutating get {
      if let object = objc_getAssociatedObject(self, &AssociatedObjectHandle) {
        return object as! Int
      }
      let index = self.searchEmptyIndex()
      self.emptyIndex = index

      return index
    }
    set {
      let new = (newValue as NSInteger)
      objc_setAssociatedObject(self, &AssociatedObjectHandle, new, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }
  }

  func searchEmptyIndex() -> Int {
      if let arr = self as? [Int] {
        return arr.index(of: -1)!
      }

      return -1
  }
}

The objc_getAssociatedObject call always returns nil!!

Anyone has any idea why?

I am banging my head for the last hour about this...


Solution

  • You cannot add associated objects to a Swift Array (or any Swift value type). objc_setAssociatedObject() and objc_getAssociatedObject() are from the Objective-C runtime, they expect an instance of NSObject as first argument.

    Your code compiles and runs only because any Swift value is automatically bridged to an object if necessary.

    • When you call objc_setAssociatedObject(self, ...) then self is bridged to a (temporary) instance of NSArray, and the association is made on that object.

    • Later, when objc_getAssociatedObject(self, ...) is called, another (temporary) instance of NSArray is created, and that has no associated object.

    That's why you get nil as the result.