2012-01-28 11 views
10

Estoy realmente comenzando el desarrollo de IOS pero tengo algunos años de desarrollo de ASP.net a través de C#. Para ser sincero, nunca antes había tenido la necesidad real de entender los delegados/eventos, etc., sé que los estoy usando cuando programo web.forms, pero gran parte de la funcionalidad está a cargo del framework, detrás de la escena .Delegados en iOS: se requieren algunas aclaraciones

Así que ahora que estoy desarrollando en IOS me veo obligado a tratar de entender cómo funcionan (supongo que la teoría de delegados/eventos es la misma en todos los idiomas, tal vez estoy equivocado). De todos modos, la siguiente línea de código en IOS:

if ([self.delegate respondsToSelector:@selector(startImporting:)]) 
{ 
      [self.delegate startImporting:self]; 
} 

Estoy en lo cierto al pensar que, en pseudo código, que significa algo en la línea de:

Si el método/clase de llamar a este método tiene una método llamado 'startImporting' y luego llama al método 'startImporting' dentro de la clase llamante.

Espero que sea claro. Si ese es el caso, entonces sería esencialmente lo mismo que tener un método estático en C# que se podría llamar con algo como:

myImportClass.startImporting(); 

Es de suponer que no, o eso es la forma en que se llevaría a cabo. Entonces, ¿me estoy perdiendo el objetivo de los delegados, sus beneficios, etc.? He leído una y otra vez y, si bien tiene sentido, nunca hace clic, nunca (en todos los formularios web) realmente he visto el beneficio de usarlos.

Esto se vuelve cada vez más importante ya que estoy usando expresiones lambda en .net y están estrechamente relacionadas con los delegados en C#, así que mientras puedo comenzar a usarlas, prefiero saber por qué y qué beneficio tienen los delegados en realidad son

+0

Aquí http://stackoverflow.com/questions/30662032/ios-callback-function -desde la biblioteca puede encontrar detalles de implementación para los delegados. –

Respuesta

45

El patrón de delegación en el cacao se utiliza para informar (informe de situación, etc. .) o consultar (solicitar credenciales, etc.) otro objeto sin saber mucho al respecto.

Normalmente, utiliza un protocolo para definir qué métodos llamará al delegado y luego el delegado debe cumplir con ese protocolo. También puede agregar métodos que el delegado no necesita implementar (opcional). Cuando lo haga, deberá llamar a -respondsToSelector :, porque no sabe si el delegado desea que se llame o no al método en particular.

Un ejemplo:
tiene una clase que produce algo, vamos a llamarlo Machine y un trabajador de la clase Worker.La máquina necesita ser ajustado para la tarea:

Machine *machine = [[Machine alloc] init]; 
[machine prepareWithParameters:myParameters]; 

Ahora que tenemos la máquina que queremos producir una enorme cantidad de Stuff:

[machine produceStuff]; 

bien, hemos terminado. Pero, ¿cómo sabemos cuándo se ha producido una unidad de Stuff? Podríamos tener nuestro trabajador constantemente de pie al lado de nuestra máquina y espere:

while (![machine isFinished]) { 
    if ([machine didProduceStuff]) { 
     Stuff *stuff = [machine producedStuff]; 
     [self doSomethingWithStuff:stuff]; 
    } 
    else { 
     // Get a very large coffee... 
    } 
} 

¿No sería grande si la máquina nos informó de forma automática, cuando se hace con la producción de una unidad de Stuff?

@protocol MachineDelegate <NSObject> 
@optional 
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff; 
@end 

Vamos a añadir el worker como delegado de machine:

Worker *worker; 
Machine *machine = [[Machine alloc] init]; 
[machine prepareWithParameters:myParameters]; 
[machine setDelegate:worker]; // worker does conform to <MachineDelegate> 

[machine produceStuff]; 

Cuando Machine se lleva a cabo la producción de algo, entonces se llamará:

if ([[self delegate] respondsToSelector:@selector(machine:didProduceStuff:)]) 
    [[self delegate] machine:self didProduceStuff:stuff]; 

El worker A continuación, recibirá este método y puede hacer algo:

- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff { 
    [self doSomethingWithStuff:stuff]; 
    if ([machine isFinished]) 
     [self shutDownMachine:machine]; 

}

no es mucho más eficiente y más fácil para el trabajador? Ahora puede hacer algo más productivo que estar parado junto a la máquina mientras la máquina todavía está produciendo. Ahora puede añadir aún más métodos para MachineDelegate:

@protocol MachineDelegate <NSObject> 
@required 
    - (void) machineNeedsMaintenance:(Machine *)machine; 
    - (void) machine:(Machine *)machine fatalErrorOccured:(Error *)error; 
    - (BOOL) machine:(Machine *)machine shouldContinueAfterProductionError:(Error *)error; 
@optional 
    - (void) machineDidEnterEcoMode:(Machine *)machine; 
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff; 
@end 

delegados también se puede utilizar para cambiar el comportamiento de un objeto sin la subclasificación que:

@protocol MachineDelegate <NSObject> 
@required 
    - (Color *) colorForStuffBeingProducedInMachine:(Machine *)machine; 
    - (BOOL) machineShouldGiftWrapStuffWhenDone:(Machine *)machine; 
@end 

Espero que pueda ayudar a entender el beneficio de Resumiendo su código usando delegados un poco.

+2

Respuesta increíblemente completa. ¡Gracias! –

+2

¡Excelente! comenzó a entender a los delegados después de leer esta respuesta :) –

+0

Este es el mejor ejemplo de delegado objetivo c que he encontrado hasta ahora –

1

Comprender el modelo MVC y el uso de Protocolos y notificaciones es fundamental para comprender el uso y el propósito de los delegados. Piense en ellos como tipos de respondedores para diferentes eventos relacionados con una acción específica.

Hera son algunos enlaces útiles en Stackoverflow:

creo que sirve

0

delegados son útiles para obtener devoluciones de llamada de otra clase

¿por qué utilizar delegado: eso es que llamamos a un método en una clase ... eso es normal ... si queremos que la clase instanciada nos dejó devolver la llamada ... Ahí es donde entra delegados en práctico ...

ejemplo sencillo: u descargar canciones de un sitio mediante un método en una clase vez que la clase finaliza la descarga u desea la clase de dejar u saber ..

//protocol declaration 
    @protocol DownloadProtocol <NSObject> 
    -(void)OnFinish; 
    @end 

//SOng download class 
@interface songs 
@property(Strong,nonatomic) id<DownloadProtcol> delegate; 
-(void)Download; 
@end 
@implementation songs 
-(void)Download 
{ 

///the code to download goes here 

[self callTheCallingClass]; 

} 

-(void)CallTheCallingClass 
{ 
[self.delegate OnFinish]; 
} 
@end 

// 
@interface mainclass<DownloadProtocol> 

@end 

@implementation mainclass 

-(void)viewDidload 
{ 
Songs *s=[[SOngs alloc]init]; 
s.delegate=self; 
[s download]; 
} 
-(void)OnFinish 
{ 
    NSlog(@"Called"); 
} 
@end 

1) Véase la delegación se logra a través del protocolo en el objetivo c Creo que u puede entender la sintaxis de la misma ...

2) En la clase de canciones que crear una propiedad para ese protocolo lo mantenemos el tipo como ID ... porque el tipo no se conoce en el momento de la compilación.

3) en la clase de canciones una vez que completamos la descarga, llamamos al método de protocolo ...

4) en la clase principal primero que adoptar el Protocolo sintaxis clase lo anterior es la sintaxis de que

5) el que una instancia de la clase canciones

6) a continuación, asignar el objeto principal de clase (auto) al delegado de clase canciones

7), entonces tenemos que aplicar la clase de protocolo en .m añadiendo el nombre del método de protocolo de

8) por lo que desde ahora en adelante cada vez que la clase canciones llamar al método a través del protocolo instancia delegado variables .... adopción método cabo PROTOCL en clase principal se ejecute

probar este código creo que sirve ...

si u quiere más información sobre este tema en google como patrón de diseño delegado

la benifit principal es Promueve imprecisa de programación ...

Cuestiones relacionadas