从名称(以String格式)中调用方法有时会很有用。 在Swift中,建议更改行为并使用闭包“动态”地进行操作,例如,您可以拥有一个函数字典,名称为键,实现为值。 但是,有时您只想简单地知道“怎么做”,这就是这个问题的原因。 那么,如何从名称作为字符串开始动态调用Swift方法?
在目标C中很简单:
[self performSelector:NSSelectorFromString(@"aSelector")];
但是performSelector在Swift中被禁止 还有其他选择吗?
performSelector
在Swift中,您应该使用闭包并更改方法。但是,如果要performSelector仅使用字符串签名就可以动态调用方法,尽管本机不支持该方法,我已经找到了实现方法。
可以创建C语言替代performSelector:
但是,实现它的完整版本并不是那么简单,并且有必要在C中创建方法。
在C语言中,我们有dlsym()这个函数,该函数返回给定给定char符号的函数的指针。好吧,阅读这篇有趣的文章:http : //www.eswick.com/2014/06/inside- swift/ 我已经学到了很多关于swift的有趣的东西。
Swift实例方法是具有特定签名的普通函数,如下所示
_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
其中“ self”值作为最后一个参数传递
简而言之,您可以直接从c端调用它,而无需任何桥接,只需重建正确的函数签名即可。在上面的签名中,有项目的名称(FirstSwiftTest)和长度(14),类的名称(ASampleClass)和长度(12),函数的名称(aTestFunction)和长度(13 ),然后将其他值作为返回类型ecc ecc。有关其他详细信息,请查看上一个链接
上面的函数是对此的表示:
class ASampleClass { func aTestFunction() -> NSString { println("called correctly") return NSString(string: "test") }
}
好吧,在C端,我能够创建此函数
#include <stdio.h> #include <dlfcn.h> typedef struct objc_object *id; id _performMethod(id stringMethod, id onObject) { // ... // here the code (to be created) to translate stringMethod in _TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString // ... id (*functionImplementation)(id); *(void **) (&functionImplementation) = dlsym(RTLD_DEFAULT, "_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString"); char *error; if ((error = dlerror()) != NULL) { printf("Method not found \n"); } else { return functionImplementation(onObject); // <--- call the function } return NULL }
然后迅速地叫它
let sampleClassInstance = ASampleClass() println(_performMethod("aTestFunction", sampleClassInstance))
该函数将这些语句打印在日志上:
称为正确 测试
因此,在C中创建_performMethod()替代方法并不难:
编辑
在Swift 2中(也许在Beta3中,我没有尝试过)似乎允许performSelector()(并且只能在NSObject子类上调用它)。检查二进制文件,现在看来Swift可以创建可由performSelector专门调用的静态函数。
我创建了这个课程
class TestClass: NSObject { func test() -> Void { print("Hello"); } } let test = TestClass() let aSel : Selector = NSSelectorFromString("test") test.performSelector(aSel)
现在在二进制文件中
000000010026d830 t __TToFC7Perform9TestClass4testfT_T_
目前,我还不太了解其背后的原因,但我将进一步调查