首页 文章

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

提问于
浏览
12

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

@objc protocol Speaker {
  func Speak()
  optional func TellJoke()
}

它说 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) .

然后,它显示了实现协议的示例:

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 doesn't conform to protocol Speaker" .

Xcode还会弹出一个 fix-it 文本,上面写着 "Candidate is not '@objc' but protocol requires it" .

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

4 回答

  • 0

    据我所知,将协议标记为@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以指定可选要求,则只能将该协议应用于类类型 .

  • 1

    为了使类型符合标记为 @objc 的协议,该类型还必须标记为 @objc ,或者用于满足协议的方法必须是 .

    在声明上使用 @objc 会告诉编译器将它暴露给Objective-C运行时 . 为了使其成为可能,声明为 @objc 的类型必须能够在Objective-C中表示 .

    对于类,这意味着它们必须从NSObject继承 . 对于方法,这意味着它们由动态Objective-C消息传递支持 .

  • 1

    看起来我们只需要在私有类中使用 @objc 作为协议方法的前缀 .

    private class A: NSObject, SomeObjcProtocol {
      @objc func someProtocolMethod() {}
    }
    

    非私人 class 的警告不太可能上升 .

    class A: NSObject, SomeObjcProtocol {
      func someProtocolMethod() {}
    }
    

    两者都很好 .

  • 10

    为协议添加一个扩展,返回空函数和默认值 . 任何符合协议并希望覆盖任何func或var的类都可以选择这样做 .

    public protocol Speaker {
          func Speak()
          func TellJoke()
        }
    
        extension Speaker {
          func Speak() {}
          func TellJoke() { print("What did the Teabag say to the Octopus?"}
        }
    

    奖金是你不继承所有的物品 Baggage .

相关问题