如何快速将void块传递给objc_setAssociatedObject [英] How do I pass in a void block to objc_setAssociatedObject in swift
问题描述
我正在尝试通过扩展程序向UIView添加轻击手势支持.使用Objective-C非常简单,但是尝试在runtime属性上设置void return块时出现以下错误.
I'm trying to add tap gesture support to UIView via an extension. This is pretty straight forward using Objective-C, but I'm getting the following error when trying to set the void return block on the runtime property.
错误:类型'()->无效'不符合协议'AnyObject'
error: type '() -> Void' does not conform to protocol 'AnyObject'
这是计算出的属性:
var tapAction: (() -> Void)? {
get {
objc_getAssociatedObject(self, &AssociatedKeys.SNGLSActionHandlerTapBlockKey)
}
set {
objc_setAssociatedObject(
self,
&AssociatedKeys.SNGLSActionHandlerTapBlockKey,
newValue,
UInt(OBJC_ASSOCIATION_COPY_NONATOMIC)
)
}
}
我尝试将tapAction设置为typealias
,但仍然收到相同的错误.
I've tried to set the tapAction as a typealias
, but still receive the same error.
推荐答案
问题是闭包不是符合AnyObject
的对象,因此不能像Swift那样存储它们.
The problem is closures are not objects that conform to AnyObject
so you can't store them like that from Swift.
您可以考虑将闭包包装在具有单个属性的类中.像这样:
You could look into wrapping the closures in a class with a single property. Something like:
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
,但这是实现它的一种方法.
It's a little ugly and could use a nice typealias
but it's one way to do it.
这篇关于如何快速将void块传递给objc_setAssociatedObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!