如何在swift中将void块传递给objc_setAssociatedObject

时间:2015-03-17 18:23:40

标签: ios swift

我尝试通过扩展程序向UIView添加点按手势支持。使用Objective-C非常简单,但是在尝试在运行时属性上设置void返回块时,我收到以下错误。

  

错误:输入'() - >虚空'不符合协议' AnyObject'

这是计算属性:

var tapAction: (() -> Void)? {

    get {
        objc_getAssociatedObject(self, &AssociatedKeys.SNGLSActionHandlerTapBlockKey)
    }

    set {

        objc_setAssociatedObject(
            self,
            &AssociatedKeys.SNGLSActionHandlerTapBlockKey,
            newValue,
            UInt(OBJC_ASSOCIATION_COPY_NONATOMIC)
        )
    }
}

我已尝试将tapAction设置为typealias,但仍会收到相同的错误。

1 个答案:

答案 0 :(得分:20)

问题是闭包不是符合AnyObject的对象,所以你不能像Swift那样存储它们。

您可以考虑使用单个属性将闭包包装在一个类中。类似的东西:

class ClosureWrapper {
  var closure: (() -> Void)?

  init(_ closure: (() -> Void)?) {
    self.closure = closure
  }
}

var tapAction: (() -> Void)? {
  get {
    if let cl = objc_getAssociatedObject(self, "key") as? ClosureWrapper {
      return cl.closure
    }
    return nil
  }

  set {
    objc_setAssociatedObject(
      self,
      "key",
      ClosureWrapper(newValue),
      UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    )
  }
}

它有点难看,可以使用一个不错的typealias,但这是一种方法。