Swift - Selector

本文介绍了Objective-C中的@selector和Swift中的Selector结构体的使用,详细阐述了如何通过selector来调用方法,包括静态和动态方式。在Objective-C中,selector用于设置target-action,检查方法响应,以及通知调用等,而在Swift中,虽然没有@selector,但可以通过字符串或#selector获取。文章还对比了两者在多参数方法名拼写上的差异,并给出了各种情况下的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@selectorObjective-C 时代的一个关键字,它可以将一个方法转换并赋值给一个SEL 类型,它的表现很类似一个动态的函数指针。在Objective-C 中selector 非常常用,从设定 target-action,到自举询问是否响应某个方法,再到指定接受通知时需要调用的方法等等,都是有selector 来负责的。在Objective-C 里生成一个selector 的方法一般是这样的:

- (void)callMe {
    // ...
}

- (void)callMeWithParam:(id)obj {
    // ...
}

SEL someMetohd = @selector(callMe);
SEL anotherMethod = @selector(callMeWithParam:);

// 也可以使用NSSelectorFromString
SEL someMetohd = NSSelectorFromString(@"callMe");
SEL anotherMethod = NSSelectorFromString(@"callMeWithParam:");

一般为了方便,很多人会选择使用@selector,但是如果要追求灵活的话,可能会更愿意使用NSSelectorFromString 的版本----因为我们可以在运行时动态生成字符串,从而通过方法的名字来调用对应的方法

在Swift 中没有@selector 了,我们要生成一个selector 的话可以使用字符串。当然方法必须被@objc 关键字修饰,如果没有@objc 修饰,则无法正常被调用,也可以使用#selector 关键字进行获取。Swift 里对应原来SEL 的类型是一个叫作Selector结构体,它提供了一个接受字符串的初始化方法。上面的两个例子在Swift 中等效的写法是:

@objc func callMe() {
	// ...
    print("aaaaaaaa")
}
    
@objc func callMeWithParam(obj: AnyObject) {
    // ...
    print(obj)
}

let someMethod = Selector.init("callMe")
let anotherMethod = Selector.init("callMeWithParamWithObj:")
print(someMethod)
print(anotherMethod)

和Objective-C 中一样,但需要注意多参数方法名拼写,即第一个参数,需要多加一个With 以及参数名,之后的参数不需要添加,如果参数被 _ 修饰时,则都无需拼写With 及参数名

@objc func callMeWithParam(_ obj: AnyObject, obj2: AnyObject) {
    // ...
    print(obj)
}
// 上面的方法为
let anotherMethod = Selector.init("callMeWithParam:obj2:")

// 修改方法参数
@objc func callMeWithParam(_ obj: AnyObject, _ obj2: AnyObject) {
    // ...
    print(obj)
}
// 上面的方法为
let anotherMethod = Selector.init("callMeWithParam::")

另外,如果方法的第一个参数有外部变量的话,需要使用外部变量,并且在第一个外部变量之加上With其他的外部变量则使用外部变量

@objc func callMeWithParam(external paramName: AnyObject) {
    // ...
    print(paramName)
}
// 上面的方法为
let anotherMethod = Selector.init("callMeWithParamWithExternal:")

// 修改方法参数
@objc func callMeWithParam(external paramName: AnyObject, exter param: AnyObject) {
    // ...
    print(paramName)
}
// 上面的方法为
let anotherMethod = Selector.init("callMeWithParamWithExternal:exter:")

其实最简单的方法就是使用#selector 关键字进行获取Selector

let method = #selector(self.callMeWithParam(external:exter:))
// 或者
let method = #selector(callMeWithParam(external:exter:))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值