El candidato no es '@objc' pero el protocolo lo requiere

He estado siguiendo este tutorial para aprender el desarrollo de aplicaciones rápidas y iOS. En la sección Protocolo, el tutorial definió el siguiente protocolo:

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

Dice que si desea tener un protocolo con methods opcionales, debe prefijar el protocolo con la label @objc (incluso si su class no está interoperando con el objective-C) .

Luego, muestra la muestra para implementar el protocolo:

 class Vicki: Speaker { func Speak() { println("Hello, I am Vicki!") } func TellJoke() { println("Q: What did Sushi A say to Sushi B?") } } 

Probé el código anterior en mi patio xcode, pero obtuve el error del comstackdor "Tipo Vicki no se ajusta al altavoz del protocolo" .

Xcode también muestra un text fijo que dice "Candidato no es '@objc', pero el protocolo lo requiere" .

Me siento completamente confundido ahora, el tutorial no menciona este error en absoluto. ¿Podría alguien explicarme todo esto para aclararme? ¡Gracias!

Por lo que puedo decir, marcar su protocolo como @objc significa que las classs que lo implementan también deben estar expuestas a Objective-C. Esto puede hacerse ya sea haciendo de Vicki una subclass de NSObject:

 class Vicki: NSObject, Speaker { 

O marcando cada método implementado como @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?") } } 

Actualización: desde la documentation de lenguaje Swift de Apple

Los requisitos de protocolo opcionales solo se pueden especificar si su protocolo está marcado con el atributo @objc.

Tenga en count también que los protocolos @objc solo pueden adoptarse por classs, y no por estructuras o enumeraciones. Si marca su protocolo como @objc para especificar los requisitos opcionales, solo podrá aplicar ese protocolo a los types de class.

Para que un tipo cumpla con un protocolo marcado @objc , ese tipo también debe estar marcado con @objc o los methods que se utilizan para satisfacer el protocolo deben serlo.

Usar @objc en una statement le dice al comstackdor que lo exponga al time de ejecución de Objective-C. Para que eso sea posible, el tipo que fue declarado @objc debe poder representarse en Objective-C.

Para las classs esto significa que deben henetworkingar de NSObject. Para los methods, esto significa que están respaldados por el paso dynamic del post Objective-C.

Parece que solo necesitamos prefijar el método de protocolo con @objc en la class privada.

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

No es probable que la advertencia aumente para la class no privada.

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

Ambos están bien

Agregue una extensión al protocolo que devuelva las funciones vacías y los valores pnetworkingeterminados. Cualquier class que se ajuste al protocolo y desee anular cualquier function o var, puede hacerlo opcionalmente .

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

Las bonificaciones son: no henetworkingas todo el equipaje obj-c.