Reputation: 16673
As I understand reflection in Swift is poorly available as of yet. I am currently in the process of converting objective-c code to swift for the sake of performance (I have noticed a considerable difference).
Now what I need is a way to call a Method using reflection. The object the method needs to be called upon extends NSObject
to enable the class to be resolved using the following code;
let clazz = NSClassFromString("MyProject.DynamicClass") as NSObject.Type;
let clazzInstance = clazz() as! NSObject;
I am able to retrieve a the number of argument and a reference to the method using the following code;
let selectorMethod = Selector("myCustomMethod:");
let numberOfArguments : UInt32 = method_getNumberOfArguments(selectorMethod);
let referenceToMethod : Method = class_getInstanceMethod(clazz, selector!);
But how do I use/call the referenceToMethod
?
Additional
I have also tried calling performSelector but this has been completely removed Swift 2. I also would like to prevent the use of any @objc
attributes/annotations.
Upvotes: 4
Views: 3810
Reputation: 10296
If you are looking for a completely Swifty way of reflection, the object that has the method that needs to be called does not need to be a NSObject at all, instead all it need is a required initializer. Have a look at below example :
class A {
required init() {}
func printSomething(s: String) {
print(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")
The advantage of using this stands on fact that you wont need to use casting at all and also calling method with wrong arguments would trigger a compile time error
Upvotes: 2
Reputation: 1281
A crazy idea, and not perfect:
you can define a var as:
var myFunctionToBe : (() -> AnyObject)?
or even set AnyObject as parameter, and then in the initiator:
init() {
myFunctionToBe = {
//do something
return whatsdone
}
}
then in reflection you can see the var myFunctionToBe, get it as:
let method = c.value as? (() -> AnyObject)
and invoke it:
method!()
or
let returnVal = method!() as? String
Upvotes: 1