候选人不是'@objc',但协议要求
我一直在关注这个教程来学习Swift和iOS应用程序开发。 在“协议”部分,教程定义了以下协议:
@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操场,但我得到了编译器错误“typesVicki不符合协议扬声器” 。
Xcode也popup一个修复它的文本说: “候选人不是'@objc',但协议要求它” 。
我现在完全混淆了,教程没有提到这个错误。 有人能向我解释一切吗? 谢谢!
从我所知道的,把你的协议标记为@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语言文档
可选协议要求只能在您的协议使用@objc属性标记时指定。
…
还要注意,@objc协议只能由类来采用,而不能通过结构或枚举。 如果您将协议标记为@objc以指定可选要求,则只能将该协议应用于类types。
为了使types符合标记为@objc
的协议,该types还必须标记@objc
或用于满足协议的方法必须是。
在声明中使用@objc
告诉编译器将其暴露给Objective-C运行时。 为了做到这一点,声明为@objc
的types必须能够在Objective-C中表示。
对于类来说,这意味着它们必须从NSObjectinheritance。 对于方法来说,这意味着它们被dynamic的Objective-C消息传递所支持。
看起来我们只需要在私有类中使用@objc
前缀协议方法。
private class A: NSObject, SomeObjcProtocol { @objc func someProtocolMethod() {} }
对于非私人课堂,警告的可能性不大。
class A: NSObject, SomeObjcProtocol { func someProtocolMethod() {} }
两者都很好。
为返回空函数和默认值的协议添加一个扩展。 任何符合协议并希望覆盖任何func或var的类都可以select这样做。
public protocol Speaker { func Speak() func TellJoke() } extension Speaker { func Speak() {} func TellJoke() { print("What did the Teabag say to the Octopus?"} }
奖金是你不inheritance所有的物品的行李。