pattern - ¿Qué son exactamente los protocolos y los delegados y cómo se utilizan en iOS?
set delegate swift 4 (3)
En su forma más simple, un delegado es un objeto que recibe mensajes de otro objeto. Y lo haces todo el tiempo.
Así que digamos que tenías coche objeto con un motor.
@interface car : NSObject
@property (nonatomic) id engine;
@end
Así podría reenviar un mensaje de arranque al motor.
[_engine start];
El motor está actuando como un delegado, solo le estás pasando un mensaje.
Los protocolos lo hacen más formal, y Xcode verificará que cumpla con los métodos requeridos u opcionales.
@property (nonatomic) id <engineDelegate> engine;
dice que el objeto del motor DEBE contener el inicio de la función porque en la definición del protocolo lo solicitó.
@protocol engineDelegate
- (void) start;
@optional
- (double) fuelLevel;
@end
¿Por qué los delegados y los protocolos son tan geniales? Bueno, debido a que el motor podría ser cualquier número de motores diferentes que podría usar en el tiempo de ejecución, podría ser un motor a reacción, un motor de combustión, un motor de modulación de fases, no importa, siempre y cuando cumpla con el protocolo. Y le dices a Xcode que se conforma agregando el delegado a la interfaz de clase.
@interface timeWarpDrive : NSObject <engineDelegate>
Estoy realmente confundido sobre el concepto de delegados y protocolos. ¿Son equivalentes a las interfaces y clases de adaptador en Java? ¿Cómo trabajan? Ninguno de los recursos que he leído fueron útiles hasta ahora. "La delegación es un patrón simple y poderoso en el que un objeto de un programa actúa en nombre de otro objeto o en coordinación con él. El objeto delegante mantiene una referencia al otro objeto, el delegado, y en el momento adecuado envía un mensaje. lo." No tengo idea de qué significa. ¿Puede alguien explicar qué son y dar un ejemplo sencillo? ¡Gracias por adelantado!
EDITAR:
Por lo que ahora entiendo,
1) delegados implementan protocolos (otro nombre para interfaces)
2) el objeto registra un delegado (que implementa un protocolo)
3) objeto puede llamar métodos de protocolo en el delegado
Por lo tanto, un delegado está conectando el objeto con el protocolo.
Por favor corrígeme si estoy equivocado.
¿Todavía no entiendo por qué el objeto en sí no puede implementar un protocolo? ¡Podría haber sido mucho más fácil!
Los protocolos son una forma de especificar un conjunto de métodos que desea que una clase implemente si quiere trabajar con una de sus clases. Los delegados y las fuentes de datos como UITableViewDelegate y UITableViewDataSource son protocolos de hecho.
Usted especifica un protocolo de esta manera:
@protocol MyProtocol <NSObject>
- (void)aRequiredMethod;
@required
- (void)anotherRequiredMethod;
@optional
- (void)anOptionalMethod;
@end
Los métodos declarados después de @required o antes de cualquier otro especificador son necesarios y las clases que desean usar su protocolo deben implementarlos todos. También puede declarar algunos métodos opcionales declarándolos después del especificador @optional.
Luego, puede especificar que una clase se "ajusta" a un protocolo (implementa los métodos requeridos) en la interfaz de la clase:
@interface MyClass <MyProtocol>
@end
Por lo general, se mantiene una referencia a un objeto conforme a un protocolo que utiliza una propiedad. Por ejemplo, para realizar un seguimiento de un delegado:
@property (nonatomic, weak) id<MyProtocol> delegate;
En este punto, en su código, solo tiene que llamar al método al que desea llamar en el objeto del cual está manteniendo la referencia y que implementa su protocolo como lo haría con cualquier otro método:
[self.delegate aRequiredMethod];
Para verificar si un objeto se ajusta a un protocolo al que puede llamar
[self.delegate conformsToProtocol:@protocol(MyProtocol)]
Para verificar si un objeto implementa un método al que puede llamar
[self.delegate respondsToSelector:@selector(anOptionalMethod)]
Para obtener más información, consulte la guía de Apple Trabajar con protocolos .
Un protocolo que se declaró con la (@protocol syntax in Objective-C)
se usa para declarar un conjunto de métodos que implementará una clase que "adopta" (declara que usará este protocolo). Esto significa que puede especificar en su código que, "no le importa qué clase se usa, siempre y cuando implemente un protocolo particular". Esto se puede hacer en Objective-C de la siguiente manera:
id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
Si lo indica en su código, entonces cualquier clase que "se ajuste" al protocolo MyProtocol se puede usar en la variable instanceOfClassThatImplementsMyProtocol
. Esto significa que el código que usa esta variable sabe que puede usar los métodos definidos en MyProtocol con esta variable en particular, sin importar de qué clase sea. Esta es una gran manera de evitar el patrón de diseño de herencia, y evita el acoplamiento apretado.
Los delegados son un uso de la característica de lenguaje de los protocolos. El patrón de diseño de delegación es una forma de diseñar su código para utilizar protocolos cuando sea necesario. En los marcos de Cocoa, el patrón de diseño delegado se utiliza para especificar una instancia de una clase que se ajusta a un protocolo particular. Este protocolo particular especifica los métodos que la clase delegada debe implementar para realizar acciones específicas en eventos determinados. La clase que utiliza el delegado sabe que su delegado forma parte del protocolo, por lo que sabe que puede llamar a los métodos implementados en determinados momentos. Este patrón de diseño es una excelente manera de desacoplar las clases, ya que hace que sea realmente fácil intercambiar una instancia delegada por otra. Todo lo que el programador debe hacer es asegurarse de que la instancia o clase de reemplazo cumpla con el protocolo necesario Métodos especificados en el protocolo)!
Los protocolos y los delegados no están restringidos solo al desarrollo de Objective-C y Mac / iOS, sino que el lenguaje de Objective-C y los marcos de Apple hacen un uso intensivo de esta característica de lenguaje impresionante y patrón de diseño.
Editar:
Por favor encuentre este ejemplo. En el UIKit framework
de Cocoa Touch, hay un protocolo UITextFieldDelegate
. Este protocolo define una serie de métodos que deben implementar las clases que son delegados de una instancia de UITextField
. En otras palabras, si desea asignar un delegado a un UITextField
(usando la propiedad del delegado), es mejor que se asegure de que esta clase se ajuste a UITextFieldDelegate
. De hecho, porque la propiedad delegada de UITextField
se define como:
@property(nonatomic, assign) id<UITextFieldDelegate> delegate
Luego, el compilador dará advertencias si le asigna una clase que no implementa el protocolo. Esto es realmente útil. Debe indicar que una clase implementa un protocolo, y al decir que sí, le está dejando saber a otras clases que pueden interactuar de una manera particular con su clase. Por lo tanto, si asigna una instancia de MyTextFieldDelegateClass
a la propiedad delegada de UITextField
, el UITextField
sabe que puede llamar a algunos métodos particulares (relacionados con la entrada de texto, selección, etc.) de su MyTextFieldDelegateClass
. Sabe esto porque MyTextFieldDelegateClass
ha dicho que implementará el protocolo UITextFieldDelegate
.
En última instancia, todo esto conduce a una mayor flexibilidad y adaptabilidad en el código de su proyecto, ¡lo cual estoy seguro de que pronto se dará cuenta después de usar esta tecnología! :)