2009-09-05 18 views
38

Vengo del modelo de evento C# y me pregunto si existe una forma estándar de notificar a varios delegados de un evento.Múltiples delegados en el objetivo C

Tengo un protocolo ClassCDelegate que deseo que implementen tanto ClassA como ClassB. ¿Existe alguna manera de asignar una instancia de ClassC tanto ClassA como ClassB como delegados sin tener que crear manualmente una lista de variables delegadas dentro de ClassC y repetirlas?

Respuesta

73

Los delegados de cacao se utilizan para lograr la inversión de control y disminuir la necesidad de subclases. Es muy posible tener múltiples delegados para un solo objeto, pero esto se hace cuando tiene sentido delegar diferentes tipos de decisiones a diferentes objetos. Un gran ejemplo de esto es WebView de WebKit, que tiene cinco delegados responsables de áreas tan diversas como la carga de recursos y la política de navegación.

El sistema delegado de eventos de C#, que permite que un objeto se registre con otro objeto para ser notificado cuando ocurre un evento en particular, es el más cercano a las varias API de notificación disponibles desde Cocoa. Los diferentes APIs que puede encontrar al otro lado son, de mayor a menor nivel:

  • NSNotificationCenter
  • NSDistributedNotificationCenter
  • CFNotificationCenter
  • notificaciones Darwin.

Todos son similares en espíritu, por lo que solo consideraré el que usaría en este caso: NSNotificationCenter.

Los observadores, como ClassA y ClassB, registran su interés en las notificaciones con NSNotificationCenter. Se puede especificar un interés en

  • notificaciones con un nombre específico de un objeto específico
  • notificaciones con un nombre específico de cualquier objeto
  • notificaciones de un objeto en particular.

Cuando se envía una notificación coincidente al centro de notificación, se notifica a los observadores invocando el método que proporcionaron en el momento del registro con el centro de notificaciones. El método siempre tiene el mismo tipo: no devuelve nada y acepta un único argumento, un objeto NSNotification.

general Se podría manejar su situación haciendo que ClassC declarar una constante para el nombre de la notificación en su archivo de cabecera, por ejemplo,

extern NSString *const ClassCSomethingDidHappenNotification; 

observadores interesados, tales como Clase A ni ClassB, a continuación, se pueden registrar su interés en este notificación:

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
    selector:@selector(handleSomethingDidHappen:) 
     name:ClassCSomethingDidHappenNotification     
     object:aClassCObject]; 

en lugar de registrar un selector y la adición de un método para el observador para manejar la devolución de llamada, puede ahora también para registrar una cola de operaciones y un bloque a ejecutar dicha cola cuando una notificación correspondiente se registró.

Cuando se produce el evento asociado con la notificación, mensajes ClassC la notificación al centro de notificación:

[[NSNotificationCenter defaultCenter] 
    postNotificationName:ClassCSomethingDidHappenNotification 
       object:self]; 

El centro de notificación pasará a mirar a través de la lista de observadores, encontrar aquellos que coincidan con esta notificación, e invocar el método apropiado.

+1

Excelente introducción a las notificaciones y sus similitudes y diferencias con los delegados. –

+1

De acuerdo, esta es una excelente desambiguación de delegados y notificaciones (oyentes). Es algo así como una línea difusa (por ejemplo, a menudo notificamos a los delegados sobre la finalización de las tareas asincrónicas) pero vale la pena entender la distinción. –

2

Solo puede tener un objeto delegado. Si desea notificar varios objetos de cambios, debe usar NSNotificationCenter y publicar mensajes NSNotification que sus objetos puedan escuchar.

+9

En realidad, esto es una convención, pero no un límite estricto. Todo el mundo tiende a pensar solo en un método 'setDelegate:', pero hay una flexibilidad ilimitada. –

3

También puede hacer que un objeto maneje el evento y luego reenviarlo a un segundo objeto.

3

También es importante tener en cuenta que las notificaciones son una calle de un solo sentido: no pueden enviar información de regreso, como pueden hacerlo los delegados. El único caso en el que desearía iterar a través de una lista de delegados es si su clase de delegación espera información retrospectiva de sus delegados.

1

Pruebe MultiDelegate le permite reenviar métodos de delegado a cualquier cantidad de objetos delegados.