使用反射调用方法

时间:2015-06-22 08:04:04

标签: swift xcode7

据我所知,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但是已经完全删除了Swift 2.我也想阻止使用任何@objc属性/注释。

2 个答案:

答案 0 :(得分: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")

使用它的优点在于你根本不需要使用转换,并且使用错误的参数调用方法会触发编译时错误

答案 1 :(得分: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