问题
I am trying to use a selector to see if a certain protocol can perform an action. When I try it like this:
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:"))
In this case, result
evaluates to false
.
But if I add the @objc
tag to the protocol, it evaluates as true
.
@objc protocol Test {
func hello()
func goodBye(a: String)
}
Why is this?
On a side note, I know that it is now recommended to use the #selector
syntax and to move away from using strings, but for various reasons, I have to use a string in this case.
EDIT: This only started happening once I migrated my project to Swift 4.2
回答1:
By default Swift generates code that is only available to other Swift code, but if you need to interact with the Objective-C runtime – all of UIKit, for example – you need to tell Swift what to do.
That’s where the @objc attribute comes in: when you apply it to a class or method it instructs Swift to make those things available to Objective-C as well as Swift code. So, any time you want to call a method from a UIBarButtonItem or a Timer, you’ll need to mark that method using @objc so it’s exposed – both of those, and many others, are Objective-C code.
Don’t worry: if you forget to add @objc when it’s needed, your code simply won’t compile – it’s not something you can forget by accident and introduce a bug.
来源:https://stackoverflow.com/questions/52988717/why-is-the-objc-tag-needed-to-use-a-selector