2015-06-22 118 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