Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 323
YanivH Avatar asked Aug 24 '17 10:08

YanivH


1 Answers

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.

like image 101
Martin R Avatar answered Nov 13 '22 06:11

Martin R