I have been following this tutorial to learn swift & iOS app development. In the Protocol section, the tutorial defined the following protocol:
@objc protocol Speaker {
func Speak()
optional func TellJoke()
}
It says If you want to have a protocol with optional methods, you must prefix the protocol with the @objc tag (even if your class is not interoperating with objective-C).
Then, it shows the sample to implement the protocol:
class Vicki: Speaker {
func Speak() {
println("Hello, I am Vicki!")
}
func TellJoke() {
println("Q: What did Sushi A say to Sushi B?")
}
}
I tried the above code in my xcode playground, but I got the compiler error "Type Vicki doesn't conform to protocol Speaker".
Xcode also pops up an fix-it text which says "Candidate is not '@objc' but protocol requires it".
I get completely confused now, the tutorial doesn't mention this error at all. Could someone please explain to me all this to make me clear? Thanks!
Protocols are used in Objective-C to declare a set of methods and properties for a class to implement. They have a similar purpose to ABCs (abstract base classes) in Python.
@objc means you want your Swift code (class, method, property, etc.) to be visible from Objective-C. dynamic means you want to use Objective-C dynamic dispatch.
From what I can tell, marking your protocol as @objc means that any classes implementing it also have to be exposed to Objective-C. This can be done either by making Vicki a subclass of NSObject:
class Vicki: NSObject, Speaker {
Or by marking each implemented method as @objc:
class Vicki: Speaker {
@objc func Speak() {
print("Hello, I am Vicki!")
}
@objc func TellJoke() {
print("Q: What did Sushi A say to Sushi B?")
}
}
Update: From Apple's Swift Language Documentation
Optional protocol requirements can only be specified if your protocol is marked with the @objc attribute.
...
Note also that @objc protocols can be adopted only by classes, and not by structures or enumerations. If you mark your protocol as @objc in order to specify optional requirements, you will only be able to apply that protocol to class types.
In order for a type to conform to a protocol marked @objc
, that type must also marked with @objc
or the methods being used to satisfy the protocol must be.
Using @objc
on a declaration tells the compiler to expose it to the Objective-C runtime. In order for that to be possible, the type that was declared @objc
must be able to be represented in Objective-C.
For classes this means they must inherit from NSObject. For methods, this means they become backed by dynamic Objective-C message passing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With