簡體   English   中英

如何在Swift的AnyClass上使用performSelector()調用類方法?

[英]How to invoke a class method using performSelector() on AnyClass in Swift?

在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)
}

使用此代碼我收到以下編譯器錯誤:

錯誤:無法使用類型為'(Selector,withObject:NSNumber)'的參數列表調用'performSelector'

我在這里錯過了什么?

AnyClass不符合開箱即用的NSObjectProtocol 我必須將aClassNSObjectProtocol以使用performSelectorperformSelector:withObject:作為NSObjectProtocol上的方法橋接到Swift):

斯威夫特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:

(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() )。

如果要在機器上執行計算,只需執行以下操作:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM