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

Cor*_*les 3 ios swift

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

错误:类型'() - > Void'不符合协议'AnyObject'

这是计算属性:

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

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

    set {

        objc_setAssociatedObject(
            self,
            &AssociatedKeys.SNGLSActionHandlerTapBlockKey,
            newValue,
            UInt(OBJC_ASSOCIATION_COPY_NONATOMIC)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图将tapAction设置为a typealias,但仍然收到相同的错误.

gre*_*heo 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)
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

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