如何使用 perform(#selector(setter:)) 使用 swift 4 设置 属性 的值?

How do you use perform(#selector(setter:)) to set the value of a property using swift 4?

我正在尝试 运行 这段代码,但它产生了意想不到的结果。

class Test: NSObject {
    @objc var property: Int = 0
}

var t = Test()

t.perform(#selector(setter: Test.property), with: 100)
print(t.property)

正在打印的值是一些垃圾数字-5764607523034233277。如何使用 perform 方法设置 属性 的值?

performSelector:withObject: 方法需要一个对象参数,因此 Swift 将基本类型 100 转换为对象引用。

setProperty: 方法(#selector(setter: Test.property) 的计算结果)采用原始 NSInteger 参数。所以它将对象引用视为整数。

由于这种不匹配,您无法以有意义的方式使用 performSelector:withObject: 调用 setProperty:

但是,您可以改用 setValue:forKey:#keyPath,因为 Key-Value 编码知道如何将对象转换为基元:

t.setValue(100, forKey: #keyPath(Test.property))

您不能使用 perform(_:with:) 来执行此操作,因为 Int 不是 arg 所必需的 NSObject 子类。要指定类型,您可以使用以下解决方法:

let setterSelector = #selector(setter: Test.property)
let setterIMP = t.method(for: setterSelector)
//Invoking setter
unsafeBitCast(setterIMP,to:(@convention(c)(Any?,Selector,Int)->Void).self)(t, setterSelector,100)

let getterSelector = #selector(getter: Test.property)
let getterIMP = t.method(for: getterSelector)
//Invoking getter
let intValue = unsafeBitCast(getterIMP,to:(@convention(c)(Any?,Selector)->Int).self)(t, getterSelector)

您可以在我的回答中找到更多详细信息和示例here