2011-10-07 15 views
11

Actualmente estoy tratando de aprender Cocoa y no estoy seguro si entiendo eso correctamente ... Se trata de delegados y controladores.¿Qué es un delegado en Cocoa y por qué debería usarlo?

Al principio: ¿Cuál es la diferencia entre los dos? A veces veo código donde una clase se llama AppController, a veces - con más o menos el mismo contenido - AppDelegate.

Por lo tanto, si lo entiendo correctamente, un delegado es un objeto simple que recibe mensajes cuando se produce un determinado evento. Por ejemplo:

@interface WindowController : NSObject <NSWindowDelegate> 
@end 

@implementation WindowController 
- (void)windowDidMiniaturize:(NSNotification *)notification { 
    NSLog(@"-windowDidMiniaturize"); 
} 
@end 

Ahora, utilizo este código para hacer que un delegado de mi window:

@interface TryingAppDelegate : NSObject <NSApplicationDelegate> { 
    NSWindow *window; 
} 

@property (assign) IBOutlet NSWindow *window; 
@property (retain) WindowController *winController; 

@end 

Con la siguiente implementación:

@implementation TryingAppDelegate 

@synthesize window; 
@synthesize winController; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    NSLog(@"-applicationDidFinishLaunching:"); 

    self.winController = [[WindowController alloc] init]; 
    [window setDelegate:winController]; 

    [self.winController release]; 
} 

@end 

Y ahora, cada vez que minimizar window, enviará un mensaje -windowDidMiniaturize: al WindowController. ¿Tengo eso correcto?

Si es así, ¿por qué no solo subclase NSWindow en lugar de preocuparse por una clase adicional de la que debe ocuparse?

Respuesta

7

Los delegados son especialmente útiles cuando desea que un objeto coordine varios otros. Por ejemplo, puede crear una subclase NSWindowController y convertirla en su delegado de ventana. Esa misma ventana puede contener varios otros elementos (como NSTextField s) de los que desea convertir el controlador de ventana en un delegado. De esta forma, no es necesario que subclases la ventana y varios de sus controles. Puede mantener todos los códigos que conceptualmente pertenecen juntos en la misma clase. Además, los delegados generalmente pertenecen al nivel de controlador del concepto Modelo-Vista-Controlador. Al crear una subclase en NSWindow, movería el código de tipo de controlador al nivel de vista.

Una clase puede adoptar cualquier cantidad de protocolos, por lo que <NSWindowDelegate, NSTextFieldDelegate> es perfectamente válido. A continuación, puede establecer su objeto como el delegado de cualquier cantidad de ventanas y campos de texto. Para averiguar qué mensajes de delegado admite una clase como NSTextField, consulte class reference. Los métodos -delegate y -setDelegate: generalmente le indicarán el protocolo adecuado. En nuestro caso, esto es NSTextFieldDelegate. Para las clases que se han agregado a la versión anterior de los marcos de Apple a menudo hay una sección adicional sobre los métodos de delegado (ya sea junto a "Métodos de clase" y "Métodos de instancia" o como una subsección de "Tareas"). Tenga en cuenta que la declaración de su clase que se ajuste a un protocolo de delegado no han mágicamente entregado a su objeto - debe establecer explícitamente como el delegado:

@interface MyWindowController : NSWindowController <NSWindowDelegate, NSTextFieldDelegate> { 
    NSTextField *_someTextField; 
} 

@property (nonatomic, retain) IBOutlet NSTextField *someTextField; 

@end 


@implementation MyWindowController 

@synthesize someTextField = _someTextField; 

- (void)dealloc { 
    [_someTextField release]; 
    [super dealloc]; 
} 

- (void)windowDidLoad { 
    [super windowDidLoad]; 
    // When using a XIB/NIB, you can also set the File's Owner as the 
    // delegate of the window and the text field. 
    [[self window] setDelegate:self]; 
    [[self someTextField] setDelegate:self]; 
} 

- (void)windowDidMiniaturize:(NSNotification *)notification { 

} 

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { 
    return YES; 
} 

@end 

AppController y AppDelegate son sólo los diferentes convenciones de nombres para el mismo tipo de clase.

+0

¡Gracias! ¿Con qué protocolo debe ajustarse mi controlador? Supongo que cuando uso NSWindowDelegateProtocol no puedo convertirlo en un delegado de 'NSTextField', ¿verdad? ¿Y qué mensajes recibo de esos elementos? Aún 'windowDidMiniaturize' y así sucesivamente? –

+0

He actualizado mi respuesta para incluir algo de información sobre (delegar) protocolos y un ejemplo. – gcbrueckmann

Cuestiones relacionadas