从Swift中的String调用方法

前端之家收集整理的这篇文章主要介绍了从Swift中的String调用方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从其名称(以String格式)调用方法有时可能很有用。
在Swift中,建议改变行为并使用闭包来“动态地”做某事,因此例如你可以有一个函数字典,名字为关键字,实现为值。
然而,有时你想简单地知道“怎么做”,这是这个问题的原因。
那么,如何动态调用一个Swift方法从它的名字作为字符串?

在Objective C中很简单:

[self performSelector:NSSelectorFromString(@"aSelector")];

但是在Swift中禁止了performSelector
有什么选择吗?

在Swift中,你应该使用闭包并改变你的方法
但是,如果你想使用performSelector来动态调用一个给定的方法只给它的String签名,但它不支持本机,我已经找到如何做到。

可以创建一个C替代performSelector:

>甚至在原生的swift类上工作(非objective-c)
>从字符串中选择一个选择器

然而,实现它的完整版本并不是那么直接,并且有必要在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_

在这个时候,我不太明白这背后的原因,但我会进一步调查

猜你在找的Swift相关文章