为什么使用选择器需要@objc标记?

时间:2018-10-25 11:56:14

标签: ios swift

我正在尝试使用选择器来查看某个协议是否可以执行操作。当我这样尝试时:

protocol Test {
    func hello()
    func goodBye(a: String)
}

class Tester: NSObject, Test {        
    override init() {}
    func hello() { }        
    func goodBye(a: String) { }
}

let a: Test = Tester()

let result = a.responds(to: Selector("goodByeWithA:"))

在这种情况下,result的值为false

但是,如果我在协议中添加@objc标签,则其评估结果为true

@objc protocol Test {
    func hello()
    func goodBye(a: String)
}

这是为什么?

另一方面,我知道现在建议使用#selector语法并远离使用字符串,但是出于各种原因,在这种情况下,我必须使用字符串。

编辑:只有当我将项目迁移到Swift 4.2后,这种情况才开始发生

1 个答案:

答案 0 :(得分:1)

默认情况下,Swift生成的代码仅对其他Swift代码可用,但是如果您需要与Objective-C运行时进行交互(例如,整个UIKit),则需要告诉Swift该怎么做。

这就是@objc属性的来源:将其应用于类或方法时,它会指示Swift将这些内容提供给Objective-C和Swift代码。因此,每次您要从UIBarButtonItem或Timer调用方法时,都需要使用@objc标记该方法,以便将其公开-这两个以及许多其他都是Objective-C代码。

不用担心:如果您忘记了在需要时添加@objc,则代码根本就不会编译-这不是您会偶然忘记并引入错误的东西。