候选人不是'@objc',但协议需要它

Lee*_*fin 12 xcode ios swift

我一直在学习这个教程,以学习swift和iOS应用程序开发.在Protocol部分,本教程定义了以下协议:

@objc protocol Speaker {
  func Speak()
  optional func TellJoke()
}
Run Code Online (Sandbox Code Playgroud)

它说如果你想拥有一个带有可选方法的协议,你必须在协议前加上@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?")
  }
}
Run Code Online (Sandbox Code Playgroud)

我在我的xcode playground中尝试了上面的代码,但是我得到了编译错误"Type Vicki不符合协议Speaker".

Xcode还会弹出一个修复文本,上面写着"候选人不是'@objc',但协议需要它".

我现在感到很困惑,教程根本没有提到这个错误.有人可以向我解释这一切让我明白吗?谢谢!

Tom*_*ott 10

据我所知,将协议标记为@objc意味着任何实现它的类也必须暴露给Objective-C.这可以通过使Vicki成为NSObject的子类来完成:

class Vicki: NSObject, Speaker {
Run Code Online (Sandbox Code Playgroud)

或者将每个实现的方法标记为@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?")
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:来自Apple的Swift语言文档

只有在协议标记为@objc属性时,才能指定可选的协议要求.

...

另请注意,@ objc协议只能由类采用,而不能由结构或枚举采用.如果将协议标记为@objc以指定可选要求,则只能将该协议应用于类类型.