2011-10-07 11 views
11

Attualmente sto cercando di imparare Cocoa e non sono sicuro di averlo capito correttamente ... Si tratta di delegati e controller.Che cos'è un delegato in Cocoa e perché dovrei usarli?

In primo luogo: qual è la differenza tra i due? A volte vedo codice in cui una classe è chiamata AppController, a volte - con più o meno lo stesso contenuto - AppDelegate.

Quindi, se ho capito bene, un delegato è un oggetto semplice che riceve messaggi quando si verifica un determinato evento. Per esempio:

@interface WindowController : NSObject <NSWindowDelegate> 
@end 

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

Ora, io uso questo codice per renderlo un delegato della mia window:

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

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

@end 

Con la seguente implementazione:

@implementation TryingAppDelegate 

@synthesize window; 
@synthesize winController; 

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

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

    [self.winController release]; 
} 

@end 

E ora, ogni volta che minimizzare window, invierà un messaggio -windowDidMiniaturize: a WindowController. Ho ragione?

Se è così, perché non si limita la sottoclasse NSWindow invece di preoccuparsi di una classe aggiuntiva di cui si deve occuparsi?

risposta

7

I delegati sono particolarmente utili quando si desidera che un oggetto ne coordini molti altri. Ad esempio, è possibile creare una sottoclasse NSWindowController e renderla delegata della finestra. Quella stessa finestra potrebbe contenere diversi altri elementi (come NSTextField s) di cui si desidera delegare il controller di finestre. In questo modo non è necessario sottoclasse la finestra e molti dei suoi controlli. È possibile mantenere tutto il codice che concettualmente appartiene insieme nella stessa classe. Inoltre, i delegati di solito appartengono al livello di controller del concetto Model-View-Controller. Con la sottoclasse di NSWindow si sposta il codice del tipo di controller al livello di visualizzazione.

Una classe può adottare qualsiasi numero di protocolli, pertanto <NSWindowDelegate, NSTextFieldDelegate> è perfettamente valido. È quindi possibile impostare l'oggetto come delegato di un numero qualsiasi di finestre e campi di testo. Per scoprire cosa delegare i messaggi a una classe come NSTextField, consulta i metodi class reference. I metodi -delegate e -setDelegate: di solito indirizzano al protocollo corretto. Nel nostro caso questo è NSTextFieldDelegate. Per le classi che sono state aggiunte alla versione precedente dei framework di Apple, esiste spesso una sezione aggiuntiva sui metodi delegate (sia a fianco di "Metodi di classe" che di "Metodi di istanza" o come sottosezione di "Attività"). Si noti che dichiarando la classe conforme a un protocollo delegato sarà non li hanno magicamente trasportato al vostro oggetto - è necessario impostare in modo esplicito come il delegato:

@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 e AppDelegate sono solo diverse convenzioni di denominazione per lo stesso tipo di classe.

+0

Grazie! A quale protocollo deve essere conforme il mio controllore? Suppongo che quando uso NSWindowDelegateProtocol non riesco a renderlo un delegato di un 'NSTextField', vero? E quali messaggi ricevo da quegli elementi? Ancora 'windowDidMiniaturize' e così via? –

+0

Ho aggiornato la mia risposta per includere alcune informazioni sui protocolli (delegato) e un esempio. – gcbrueckmann

Problemi correlati