簡體   English   中英

候選人不是'@objc',但協議需要它

[英]Candidate is not '@objc' but protocol requires it

我一直在學習這個教程,以學習swift和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',但協議需要它”

我現在感到很困惑,教程根本沒有提到這個錯誤。 有人可以向我解釋這一切讓我明白嗎? 謝謝!

據我所知,將協議標記為@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以指定可選要求,則只能將該協議應用於類類型。

為了使類型符合標記為@objc的協議,該類型還必須用@objc標記,或者用於滿足協議的方法必須是。

在聲明上使用@objc告訴編譯器將它暴露給Objective-C運行時。 為了使其成為可能,聲明為@objc的類型必須能夠在Objective-C中表示。

對於類,這意味着它們必須從NSObject繼承。 對於方法,這意味着它們由動態Objective-C消息傳遞支持。

看起來我們只需要在私有類中使用@objc作為協議方法的前綴。

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

非私人班級的警告不太可能上升。

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

兩者都很好。

為協議添加一個擴展,返回空函數和默認值。 任何符合協議並希望覆蓋任何func或var的類都可以選擇這樣做。

    public protocol Speaker {
      func Speak()
      func TellJoke()
    }

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

獎金是你不繼承所有的物品行李。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM