swift 中的 selector

2018/9/20 posted in  iOS

首先,@selector方法选择器是OC中很常用的一个关键字,无论是计时器相应方法,通知效应方法,按钮相应方法,自省判断是否能相应某个方法,都会用到@selector,OC中常用生成@selector的格式如下:

- (void)func1{
}
 
- (void)func1With:(id )obj{
}
 
//生成选择器方法如下
SEL selector1 = @selector(func1);
SEL selector2 = NSSelectorFromString(@"func1");
SEL selector3 = @selector(func1With:);
SEL selector4 = NSSelectorFromString(@"func1With:");

在swift中没有@selector了,从swift2.2开始,我们开始用#selector来从暴露给OC的代码中,获取一个选择器。类似的,swift中类似于SEL的是一个叫做Selector的结构体,上述生成SEL的代码,在Swift中类似的实现方式如下:

@objc func func1() {
}

@objc func func2(with obj:Any ) {
}

let selector1 = #selector(func1)
let selector2 = #selector(func2(with:))

在swift4.0中,所有的swift方法都默认是OC不可见得。如果想让OC调用某些swift方法,需要在方法前面添加@objc关键字,以此暴露给OC。swift3.0及其之前,只要是NSObject的子类,编译器都会在非private得方法前默认加上@objc,此举会恶化编译器编译速度。如果此对象中有大量的OC调用,可以在类型前加@objcMembers关键字,所有非private方法都默认暴露给OC

最后,如果swift中两个相同命名,参数不同方法,直接生成Selector会产生二义性报错。遇此情况,添加上参数和返回值类型,强转即可。

@objc func func1() {
}

@objc func func1(with obj:Any ) {
}

//如此生成即可
let selector1 = #selector(func1 as ()->Void)