2009-08-28 9 views
12

Conozco una buena parte de Objective-C y estoy trabajando en un libro SDK de iPhone (procedente de un libro de Obj-C que acaba de hacer programas de consola). Intentó explicarles a los delegados que se apresuraron y no entendieron realmente lo que intentaban transmitir. Estoy un poco confundido sobre lo que son y cuándo los usarías.Poco confundido con los delegados en Objective-C

Básicamente dice que son clases que se hacen responsables de hacer ciertas cosas en nombre de otro objeto.

¿Alguien se preocupa por elaborar?

Gracias!

+2

Tuve un momento difícil con esto cuando comencé a mirar a Cocoa. No estas solo. – jergason

Respuesta

6

Una buena forma de entender a los delegados es a través del ejemplo. Un ejemplo es UITableView (o NSTableView, dependiendo de si estamos hablando de iPhone o Mac OS). De cualquier manera, la vista de tabla tiene un delegate y un dataSource (ambos actúan como objetos auxiliares del receptor).

En lugar de UITableView manejar los eventos cuando, por ejemplo, una de sus filas es tocada por un usuario, en su lugar dice delegate "¡Hola! Me han tocado esta fila y esta sección, ¡hagan lo que quieran! ". Normalmente, el delegate es un controlador de algún tipo, que implementa el método correcto. Por lo que la vista de tabla (después de comprobar para ver si el delegate en realidad tiene una definición para el método) envía un mensaje como este:

[delegate tableView:self didSelectRowAtIndexPath:indexPath]; 

Debido a que su controlador es el delegado de la mesa, y se implementa este método, se decide qué que hacer. Cuando el método finalice (en este caso, simplemente debe devolver void), la ejecución continúa en la vista de tabla.

Los delegados son un concepto. No es una función de lenguaje de Objective-C. El miembro delegate de UITableView es como cualquier otro objeto. Aunque los delegados normalmente son no retenidos, en su lugar se asignan (para evitar retain ciclos).

Son muy útiles cuando les agarras el truco. Sugiero practicar con ejemplos como TableViews (NSTableView, como dije antes, funciona de manera similar, solo con diferentes métodos).

+0

Así que son una clase a la que recurre un Objeto cuando se hace algo por sí mismo. Y dependiendo de lo que se hizo a sí mismo, llama a cierto método de la clase del delegado. ¿Correcto? ¿Es una forma adecuada de crear una clase de delegado, o es simplemente otra clase ordinaria con métodos a los que llaman otras clases? –

+1

Técnicamente, el delegado es un objeto. Puede tener cincuenta instancias de un objeto que implemente algunos métodos de delegado, pero solo la instancia que se establece como el delegado tiene sus métodos llamados. La forma correcta de crear un delegado es definir un protocolo, que define un conjunto de métodos que deben/pueden implementarse. – johnw188

+1

@Avizz: Tienes razón, un delegado puede ser cualquier tipo de objeto que desees. Aunque típicamente será uno que 'se ajuste a un protocolo'. Si un objeto se ajusta a un protocolo determinado, básicamente significa "Prometo que he implementado todo lo que se requiere de mí en el protocolo dado." De esta manera, cuando un objeto envía un mensaje a un delegado, tienen confianza de que el delegado sabe qué hacer – jbrennan

7

Digamos que desea presentar al usuario una alerta y desea que se ejecute un método cuando el usuario toca uno de los botones. El problema es, ¿cómo sabes qué método llamar, en qué objeto, cuando alguien toca un botón?

Para que una clase sea delegada, debe declararla como tal. En el ejemplo anterior, supongamos que tiene un objeto ApplicationController que controla el flujo de su aplicación. En la declaración, diríamos

@interface ApplicationController : NSObject <UIAlertViewDelegate> 

Esto le dice al compilador que ApplicationController va a aplicar algunos métodos en el protocolo UIAlertViewDelegate. Buscamos ese protocolo en nuestra documentación y vemos una lista de métodos. Como queremos hacer algo cuando se presiona un botón, vemos:

alertView:clickedButtonAtIndex: - Enviado al delegado cuando el usuario hace clic en un botón en una vista de alerta. Este método es opcional.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

Por lo tanto, si ponemos en práctica un método en el ApplicationController llamados alertView:clickedButtonAtIndex, crear un objeto ApplicationController, a continuación, establezca ese objeto como el delegado de una alerta mostramos, todo está preparado. Tan pronto como alguien presiona un botón en la alerta, se llamará al método alertView:clickedButtonAtIndex, pasando el alertView y el índice del botón presionado.

Esto le permite hacer lo que quiera con esa información. Una declaración simple caso:

if(buttonIndex == 0) { 
    _myString = @"Pressed the button"; 
} else { 
    _myString = @"Pressed the other button"; 
} 

Los documentos de referencia de Objective-C son muy, muy bueno, y todos los protocolos de los delegados son bastante explica por sí mismo.

+0

¿Qué significa el símbolo at? –

+1

Depende de a cuál te refieres. Puede definir las cadenas en su lugar diciendo @ "string here", que es una cosa sintáctica objetiva. De lo contrario, @interface es una declaración de clase. Muchos objetos específicos c comienzan con @, ya que nunca se usan en identificadores C/C++. Permite a los desarrolladores del objetivo c asegurar que no haya confusión en cuanto a si algo es de C/C++ u objetivo c – johnw188

20

Considere delegados como inversión la dirección de las dependencias. En la mayoría de los marcos, los clientes inyectarán las dependencias requeridas en instancias, generalmente en el constructor o por instaladores.

Cocoa hace lo contrario; las instancias en cambio solicitan los datos cuando y si es necesario.

Hay cuatro tipos principales de métodos de delegado:

  • condicionalmente antes - Señales de que algo está a punto de suceder, pero el delegado puede abortar. Nombre siempre incluye la palabra Deber.
    Ejemplo: searchBarShouldEndEditing:.
  • Incondicionalmente antes de - Señales de que algo va a suceder. Nombre siempre incluye la palabra voluntad.
    Ejemplo: applicationWillTerminate:.
  • Incondicionalmente después de - Señales de que algo ha sucedido. Nombre siempre incluye la palabra did.
    Ejemplo: applicationDidFinishLaunching:.
  • Personalizadores - Solicitar información sobre cómo funcionar. El nombre incluye la información que se requiere.
    Ejemplo tableView:viewForHeaderInSection:.

Todos los métodos delegados siempre tienen su remitente como uno de los argumentos. Cualquier método de delegado puede tener un valor de retorno que altere el comportamiento del remitente.

+1

Sin duda la mejor explicación entre estas respuestas, imho –

2

Un delegado (que significa representante) es un objeto de clase (que también quiere representar (heredar)) otra clase no relacionada.El objeto delegado puede heredar de una clase no relacionada de otra manera "conformándose a" (teniendo algunas implementaciones) los métodos de protocolo requeridos de la clase no relacionada, que indican a la clase extranjera que este objeto ahora puede volcar su información más básica apropiadamente.

Se utilizan herencia cuando se quiere relacionados clases para compartir métodos. Utiliza delegados cuando desee clases no relacionadas para compartir métodos. El enfoque de delegado permite que un objeto de una clase herede métodos de una clase no relacionada de otra manera. El "objeto delegado" u "objeto representativo" es el objeto que hereda de una clase extranjera; se designa como un representante, un delegado, de esa clase remota, de modo que cuando se asigna un objeto como delegado a una clase, también le está dando permiso para representar esa clase, aunque normalmente no hereda de esa clase . (Si heredó de la clase, entonces no necesitaría establecerlo como un delegado de esa clase, ya tendría acceso a los métodos de la clase. Pero desea que este objeto no relacionado herede algunos métodos de la clase, representando eso clase, y devolver alguna información a su clase de remitente, por lo que lo convierte en un delegado representante de esa clase, aunque hereda de un conjunto diferente de clases.) Esto esencialmente permite que una clase no relacionada herede de otra clase no relacionada, pero con una mínimo de complicaciones a su línea básica de herencia.

Utiliza el sistema de delegado cuando desea que un objeto ejecute código de una clase separada. Por ejemplo, as described here, cuando presiona Intro en un campo de texto, el campo de texto realmente no sabe qué hacer con esa información. Lo que hace es mirar a la clase de su objeto delegado (como el controlador de ventana del documento o el documento) y utiliza el método relevante de esa clase que se ajusta al método respectivo del campo de texto encontrado dentro de su protocolo delegado de campo de texto, algo así como textFieldShouldReturn. Entonces, en este caso, configura el controlador de ventana o el documento como el delegado del campo de texto, porque el campo de texto necesita esa clase para representar la información que se le dio.

Clase A necesita un método de Clase B, Clase A, pero no hereda de la clase B. En primer lugar, decirle al compilador que la Clase A cumple con el protocolo de Clase B:

@interface ClassA : NSObject <ClassBDelegateProtocol> 

en la documentación de Apple, cada referencia de clase muestra en la parte superior, "Hereda de" y "Cumple con". Por ejemplo, NSDocumentController hereda de NSObject y se ajusta a NSUserInterfaceValidations, NSCoding y NSObject(NSObject). La conformidad a NSCoding es de la declaración de interfaz en NSDocumentController.h

@interface NSDocumentController : NSObject <NSCoding> 

y para NSUserInterfaceValidations de la declaración del método en NSDocumentController.h

-(BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item; 

junto con el #import

#import <AppKit/NSUserInterfaceValidation.h> 

Así mientras que NSDocumentController hereda de NSObject, también necesita ayuda delNSCoding y NSUserInterfaceValidation. Y obtiene ayuda de estas clases extranjeras por según sus métodos de protocolo, definiéndose a sí mismo como conforme a los métodos y importando los archivos de encabezado necesarios para usar esos métodos.

0

No estás solo, todavía estoy aprendiendo esto por mi cuenta. Creo que es mejor si trato de explicarlo en palabras en lugar de código. Existe un protocolo que contiene un determinado método o acción que desea lograr. El delegado toma el método del protocolo para poder usarlo para facilitar una acción o método. Encontré este artículo para ser muy útil http://rypress.com/tutorials/objective-c/protocols. Espero que esto ayude.