Swift4.0中调用Selector采用#selector(xxx)的方式,而且要求被调用的Selector前面加上@objc修饰符。否则编译器报错 如图所示。
有时候项目中会有一些特殊的需求,需要用到NSSelectorFromString(),然后使用 perform(_ aSelector: Selector!) -> Unmanaged
1 | let sel: Selector = NSSelectorFromString("doSomething") |
这样调用的话,需要在实现方法的前面也加上@objc修饰符,否则编译可以通过,但是调用没有效果。
1 | // 代码示例 |
看起来和OC中使用差别并不大,但是如果被调用的方法带参数的话,情况就不一样了。由于Swift的语法特性,带参数的func有3种写法:
1 |
|
这样一来,NSSelectorFromString(“xxx”)中,方法名该如何填写呢?
这里有一个思路,既然方法名前面都有@objc修饰符,那我们应该是可以通过runtime,将这些方法获取并打印出来,那么方法名就一览无余啦。
接下来在Swift中建一个OC类文件做一个工具类,之后再桥接上头文件。
1 | // 导入runtime头文件 |
工具搞好了,创建一个Swift对象,用工具类打印出方法,得出如下结果:
1 | 2018-03-13 18:03:51.163992+0800 SwiftOCDemo[92116:21107487] 方法名:doSomething1WithName:type:,参数个数:4,编码方式:v32@0:8@16@24 |
果然,Swift4中带参数的方法名在写法不同的情况下,生成的方法名是不同的,最终我们根据输出结果,就可以放心调用啦!
1 | let sel1 = NSSelectorFromString("doSomething1WithName:type:") |
虽然需求得以实现,不过在此还是提醒大家,Swift语言的初衷是为大家提供方便并且安全的开发方式,这种通过NSSelectorFromString(“xxx”)的方式显然是违背设计原则的,大家在开发的过程中尽量避免使用这种方式。当然,遇到坑爹的需求就另说了,毕竟技术要服务于业务嘛。。。
还有一点就是,我在Swift提供的perform()方法中只发现了这几个func
如果你要调用的方法多于两个参数的话,那就得考虑一下用何种方案了。