如何在Swift的AnyClass上使用performSelector()调用类方法? [英] How to invoke a class method using performSelector() on AnyClass in Swift?
问题描述
在ObjC中,您可以简单地使用NSObject
中的类方法来调用类方法.
In ObjC you could simply invoke a class method using the class method from NSObject
.
[Machine performSelector:@selector(calculate:) withObject:num];
但是您如何在Swift 2.2中做到这一点?
But how do you do this in Swift 2.2?
@objc(Machine) // put it here, so you can simply copy/paste into Playground
class Machine: NSObject {
static func calculate(param: NSNumber) -> String {
if param.integerValue > 5 {
return "42"
}
return "42" // there is only 1 answer to all the questions :D
}
}
if let aClass = NSClassFromString("Machine") {
let sel = #selector(Machine.calculate(_:))
let num = NSNumber(integer: 1337)
let answer = aClass.performSelector(sel, withObject: num) // compiler error
// let answer = aClass.calculate(num) // <-- this works
print(answer)
}
使用此代码,我得到以下编译器错误:
With this code I'm getting the following compiler error:
错误:无法使用类型为'(Selector,withObject:NSNumber)'的参数列表调用'performSelector'
error: cannot invoke 'performSelector' with an argument list of type '(Selector, withObject: NSNumber)'
我在这里想念什么?
推荐答案
AnyClass
不符合NSObjectProtocol
的规定.我必须将aClass
转换为NSObjectProtocol
才能使用performSelector
(performSelector:withObject:
作为NSObjectProtocol
上的方法桥接到Swift):
AnyClass
does not conform to NSObjectProtocol
out of the box. I had to cast aClass
as NSObjectProtocol
to use performSelector
(performSelector:withObject:
is bridged to Swift as a method on NSObjectProtocol
):
迅速3:
if let aClass = NSClassFromString("Machine") {
let sel = #selector(Machine.calculate(param:))
let num = NSNumber(value: 1337)
if let myClass = aClass as? NSObjectProtocol {
if myClass.responds(to: sel) {
let answer = myClass.perform(sel, with: num).takeRetainedValue() // this returns AnyObject, you may want to downcast to your desired type
print(answer) // "42\n"
}
}
}
Swift 2.x:
Swift 2.x:
(aClass as! NSObjectProtocol).performSelector(sel, withObject: num) // Unmanaged<AnyObject>(_value: 42)
更安全一点:
if let aClass = NSClassFromString("Machine") {
let sel = #selector(Machine.calculate(_:))
let num = NSNumber(integer: 1337)
if let myClass = aClass as? NSObjectProtocol {
if myClass.respondsToSelector(sel) {
let answer = myClass.performSelector(sel, withObject: num).takeUnretainedValue()
print(answer) // "42\n"
}
}
}
performSelector
返回一个Unmanaged
对象,这就是为什么需要takeUnretainedValue()
(如果要转移内存所有权,也可以选择takeRetainedValue()
)的原因.
performSelector
returns an Unmanaged
object, that's why takeUnretainedValue()
(or optionally takeRetainedValue()
if you want to transfer memory ownership) are required.
这篇关于如何在Swift的AnyClass上使用performSelector()调用类方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!