我一直关注这个tutorial来学习快速和iOS应用开发。在Protocol部分,本教程定义了以下协议:
@objc protocol Speaker {
func Speak()
optional func TellJoke()
}
它说如果你想拥有一个带有可选方法的协议,你必须在协议前加上@objc标签(即使你的类没有与objective-C互操作)。
然后,它显示了实现协议的示例:
class Vicki: Speaker {
func Speak() {
println("Hello, I am Vicki!")
}
func TellJoke() {
println("Q: What did Sushi A say to Sushi B?")
}
}
我在我的xcode playground中尝试了上面的代码,但是我得到了编译器错误" Type Vicki并不符合协议Speaker" 。
Xcode还会弹出修复文字,上面写着"候选人不是' @ objc'但协议需要它" 。
我现在感到很困惑,教程根本没有提到这个错误。有人可以向我解释这一切让我明白吗?谢谢!
答案 0 :(得分:10)
据我所知,将协议标记为@objc意味着任何实现它的类也必须暴露给Objective-C。这可以通过使Vicki成为NSObject的子类来完成:
class Vicki: NSObject, Speaker {
或者将每个实现的方法标记为@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?")
}
}
更新:来自Apple的Swift Language Documentation
如果您的协议标有@objc属性,则只能指定可选的协议要求。
...
另请注意,@ objc协议只能由类采用,而不能 通过结构或枚举。如果您将协议标记为@objc in 为了指定可选要求,您将只能申请 类协议的类协议。
答案 1 :(得分:1)
为了使类型符合标记为@objc
的协议,该类型还必须标有@objc
,或者用于满足协议的方法必须是。
在声明上使用@objc
告诉编译器将它暴露给Objective-C运行时。为了使其成为可能,声明为@objc
的类型必须能够在Objective-C中表示。
对于类,这意味着它们必须从NSObject继承。对于方法,这意味着它们由动态Objective-C消息传递支持。
答案 2 :(得分:1)
看起来我们只需要在私有类中使用@objc
作为协议方法的前缀。
private class A: NSObject, SomeObjcProtocol {
@objc func someProtocolMethod() {}
}
非私人班级的警告不太可能上升。
class A: NSObject, SomeObjcProtocol {
func someProtocolMethod() {}
}
两者都很好。
答案 3 :(得分:0)
为协议添加一个扩展,返回空函数和默认值。任何符合协议且希望覆盖任何func或var的类都可以选择这样做。
public protocol Speaker {
func Speak()
func TellJoke()
}
extension Speaker {
func Speak() {}
func TellJoke() { print("What did the Teabag say to the Octopus?"}
}
奖金是你不会继承所有物品行李。