6

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...

YanivH
  • 539
  • 4
  • 18

1 Answers1

12

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382