2011-10-07 10 views
11

Obecnie próbuję nauczyć się Cocoa i nie jestem pewien, czy rozumiem to poprawnie ... To około delegatów i kontrolerów.Co to jest delegat w Cocoa i dlaczego powinienem z nich korzystać?

Na początku: Jaka jest różnica między tymi dwoma? Czasami widzę kod, w którym klasa nazywa się AppController, czasami - z mniej więcej taką samą zawartością - AppDelegate.

Tak więc, jeśli rozumiem to poprawnie, delegat jest prostym obiektem, który odbiera komunikaty po wystąpieniu określonego zdarzenia. Na przykład:

@interface WindowController : NSObject <NSWindowDelegate> 
@end 

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

Teraz używam tego kodu, aby go delegatem mojego window:

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

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

@end 

z następującymi realizacji:

@implementation TryingAppDelegate 

@synthesize window; 
@synthesize winController; 

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

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

    [self.winController release]; 
} 

@end 

i teraz, ilekroć zminimalizować window, wyśle ​​wiadomość -windowDidMiniaturize: do WindowController. Czy mam to prawo?

Jeśli tak, to dlaczego nie po prostu podklasujesz NSWindow zamiast zajmować się dodatkową klasą, którą musisz zająć?

Odpowiedz

7

Delegaci są szczególnie przydatni, gdy chcemy, aby jeden obiekt koordynował kilka innych. Na przykład możesz utworzyć podklasę NSWindowController i sprawić, że będzie to delegat okna. To samo okno może zawierać kilka innych elementów (np. NSTextField s), które mają sprawić, że kontroler okien będzie delegatem. W ten sposób nie trzeba podklasować okna i kilku jego kontrolek. Możesz zachować cały kod, który koncepcyjnie należy do siebie w tej samej klasie. Ponadto delegaci zazwyczaj należą do poziomu kontrolera w koncepcji Model-widok-kontroler. Podklasując NSWindow przeniesiesz kod typu kontrolera do poziomu widoku.

Klasa może przyjąć dowolną liczbę protokołów, więc <NSWindowDelegate, NSTextFieldDelegate> jest całkowicie poprawny. Następnie możesz ustawić obiekt jako delegat dowolnej liczby okien i pól tekstowych. Aby dowiedzieć się, jakie wiadomości delegatów są obsługiwane przez klasę, taką jak NSTextField, sprawdź metody class reference. Metody te zazwyczaj wskażą prawidłowy protokół. W naszym przypadku jest to NSTextFieldDelegate. W przypadku klas, które zostały dodane do starszej wersji frameworków Apple, często istnieje dodatkowa sekcja dotycząca metod delegowania (obok "Metody klas" i "Metody instancji" lub jako podsekcja "Zadania"). Zauważ, że deklarując swoją klasę jako zgodne z protokołem delegat nie je magicznie dostarczane do obiektu - należy jawnie ustawić go jako delegata:

@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 i AppDelegate są po prostu różne konwencje nazewnictwa dla tego samego typu klasa.

+0

Dziękujemy! Jakiego protokołu potrzebuje mój kontroler? Domyślam się, że kiedy używam NSWindowDelegateProtocol, nie mogę uczynić go delegatem 'NSTextField', prawda? A jakie wiadomości otrzymuję z tych elementów? Nadal 'windowDidMiniaturize' i tak dalej? –

+0

Zaktualizowałem swoją odpowiedź, dodając kilka informacji na temat (delegatów) protokołów i przykład. – gcbrueckmann

Powiązane problemy