如何在Swift的AnyClass上使用performSelector()调用类方法?

时间:2016-03-24 19:07:18

标签: ios swift reflection performselector swift2.2

在ObjC中,您只需使用NSObject中的类方法调用类方法。

[Machine performSelector:@selector(calculate:) withObject:num];

但是你如何在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)
}

使用此代码我收到以下编译器错误:

  

错误:无法调用&#39; performSelector&#39;使用类型&#39;(Selector,withObject:NSNumber)&#39;

的参数列表

我在这里缺少什么?

2 个答案:

答案 0 :(得分:12)

userId不符合开箱即用的AnyClass。我必须将NSObjectProtocol转换为aClass才能使用NSObjectProtocolperformSelector作为performSelector:withObject:上的方法桥接到Swift:

斯威夫特3:

NSObjectProtocol

Swift 2.x:

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"
        }
    }
}

更安全一点:

(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())的原因。

答案 1 :(得分:-1)

如果您想在机器上执行计算,请执行以下操作:

Machine.calculate(NSNumber(integer: 1337))

如果您需要调用执行选择器,请执行:

if let aClass = NSClassFromString("Machine") as? AnyObject
{
    let sel = #selector(Machine.calculate(_:))
    let num = NSNumber(integer: 1337)
    let answer = aClass.performSelector(sel, withObject: num)
    print(answer)
}