protocolos - Swift debería usar protocolo o protocolo: clase
que es un protocolo en swift (5)
Versión Swift 4
AnyObject
agregado a una definición de protocolo como esta
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(parameters:[String: String]?)
}
significa que solo una clase podrá cumplir con ese protocolo.
Así que dado esto
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(parameters:[String: String]?)
}
Podrás escribir esto
class Foo: FilterViewControllerDelegate {
func didSearch(parameters:[String: String]?) { }
}
pero NO esto
struct Foo: FilterViewControllerDelegate {
func didSearch(parameters:[String: String]?) { }
}
Versión Swift 3
:class
agregada a una definición de protocolo como esta
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
significa que solo una clase podrá cumplir con ese protocolo.
Así que dado esto
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
Podrás escribir esto
class Foo: FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?) { }
}
pero NO esto
struct Foo: FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?) { }
}
He configurado un protocolo para enviar información al VC anterior.
Lo estoy definiendo así:
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
Pero cual es la diferencia cuando se usa:
protocol FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?)
}
¿Y cuándo debo usar un protocolo de : class
?
Actualización de Swift 3.2:
Para declarar protocolo de solo clase ahora escribe:
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
en lugar de
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here
}
El segundo fragmento todavía parece funcionar por ahora. Referencia: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
Significa que el protocolo que definas solo puede ser adoptado por clases, no por estructuras o enumeraciones.
Del libro oficial de Swift :
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here }
En el ejemplo anterior, SomeClassOnlyProtocol solo puede ser adoptado por los tipos de clase. Es un error en tiempo de compilación escribir una definición de estructura o enumeración que intenta adoptar SomeClassOnlyProtocol.
También hay otra cosa acerca de marcar protocolos con la palabra clave ''clase''.
Así que ese es tu protocolo:
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
Por ejemplo, supongamos que está creando un DetailVC, que tiene una propiedad de delegado:
class DetailViewController: UISomeViewController {
weak var delegate: FilterViewControllerDelegate
}
Si no marcase ese protocolo con una palabra clave de "clase", tampoco podría marcar esa propiedad de "delegado" como "débil".
¿Por qué?
Es simple: solo las propiedades basadas en clases pueden tener relaciones débiles. Si estás tratando de evitar un ciclo de referencia, the ese es el camino a seguir
Swift 4.1, sintaxis de Xcode 9.3:
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(Parameters:[String: String]?)
}
Este protocolo solo puede ser adoptado por clases.
Para contestar tu primera pregunta -
Pero cual es la diferencia cuando se usa:
La diferencia de esto:
protocol FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?)
}
es que este protocolo puede adoptar tipos de valor, como enumeraciones y estructuras también.
Para contestar tu segunda pregunta -
¿Y cuándo debo usar una clase: protocal?
cuando debería usar el protocolo de clase, me gustaría describir el siguiente ejemplo del patrón de delegado: imagine que tiene un protocolo de delegado.
protocol PopupDelegate: AnyObject {
func popupValueSelected(value: String)
}
y en otra clase quieres crear una propiedad.
var delegate: PopupDelegate?
Pero esto tiene una referencia fuerte que podría traerle problemas con las fugas de memoria. Una forma de corregir la pérdida de memoria es hacer que la propiedad del delegado sea débil. Hasta que no pongamos nuestro protocolo solo disponible para solicitar clases, Swift piensa que podríamos aplicar nuestro protocolo también a los tipos de valor.
weak var delegate: PopupDelegate?
Si intenta declarar a su delegado como débil, verá el siguiente error:
''débil'' var solo se aplica a los tipos de protocolo de clase y de clase, no a ''PopupDelegate''
Pero no podemos aplicar débil a los tipos de valor. Por lo tanto, necesitamos restringir nuestro protocolo a un tipo de referencia, por lo que Swift sabe que es un tipo de referencia. Para que esté disponible para declarar a este delegado como débil, debe restringir su protocolo para que lo utilicen solo las clases:
protocol PopupDelegate: AnyObject {
func popupValueSelected(value: String)
}