2015-06-22 196 views
4

據我所知,在Swift中的反射尚不可用。我目前正在將Objective-C代碼轉換爲swift以提高性能(我注意到了相當大的差異)。使用反射的調用方法

現在我需要的是一種使用反射來調用Method的方法。該方法需要調用的對象擴展爲NSObject以使該類能夠使用以下代碼進行解析;

let clazz = NSClassFromString("MyProject.DynamicClass") as NSObject.Type; 
let clazzInstance = clazz() as! NSObject; 

我能夠使用下面的代碼檢索參數的數量和引用方法;

let selectorMethod = Selector("myCustomMethod:"); 

let numberOfArguments : UInt32 = method_getNumberOfArguments(selectorMethod); 
let referenceToMethod : Method = class_getInstanceMethod(clazz, selector!); 

但是,如何使用/致電referenceToMethod

附加
我也打過電話performSelector但這已完全刪除斯威夫特2.我也想避免使用任何@objc屬性/註解。

+0

請問爲什麼你絕對需要反思?你的用例的一個例子?我相信幾乎所有東西都可以在編譯時用Swift靜態完成,這就是Swift的全部內容 – Kametrixom

+0

我沒有一個代碼示例atm,但是例如我想從一個可以指定的「框架」中加載一個模塊動態地從UI代碼中調用,無需程序員知道哪些模塊可用,因爲可以稍後由其他人添加模塊。 – Thys

回答

1

如果您正在尋找完全Swifty的反射方式,那麼需要調用該方法的對象根本不需要是NSObject,而只需要一個必需的初始化程序。看看下面的例子:

class A{ 

    required init(){ 

    } 
    func printSomething(s:String){ 

     println(s) 
    } 
} 

// initializing object dynamically from class 
let clazz = NSClassFromString("MyProject.A") as! A.Type 
let clazzInstance = clazz() 

// getting and calling its methods in Swifty way  
let method = clazzInstance.printSomething 
method("something") 

使用本的優勢站在事實,你不會需要使用的所有鑄造並調用方法與錯誤的參數會引發一個編譯時錯誤

+0

但是如果我在運行期間只有方法的名稱會怎麼樣?我不知道該方法的名稱。所以我有一個字符串值「printSomething」,那我該怎麼稱呼它呢? – Thys

+0

恐怕沒有像ObjC這樣的performSelector這樣簡單的方法。我認爲你應該在每個方法案例中寫一個switch語句 –

+0

你知道這樣的功能很快會出現在swift嗎? – Thys

0

一個瘋狂想法,不完美:

你可以定義一個VAR爲:

var myFunctionToBe : (() -> AnyObject)? 

甚至設置AnyObject作爲參數, 然後在引發劑:

init() { 
    myFunctionToBe = { 
     //do something 
     return whatsdone 
    } 
} 

然後反射,你可以看到VAR myFunctionToBe,獲得的是:

let method = c.value as? (() -> AnyObject) 

並調用它:

method!() 

let returnVal = method!() as? String