Что такое делегат в Cocoa и почему я должен их использовать?

в настоящее время я пытаюсь узнать какао, и я не уверен, правильно ли я это понимаю... Речь идет о представители и контроллеры.

сначала: в чем разница между ними? Иногда я вижу код, где класс называется AppController, иногда - с более или менее одинаковое содержание - AppDelegate.

Итак, если я правильно понимаю, делегат-это простой объект, который получает сообщения при возникновении определенного события. Для пример:

@interface WindowController : NSObject <NSWindowDelegate>
@end

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

теперь я использую этот код, чтобы сделать его делегатом моего window:

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

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

@end

со следующей реализацией:

@implementation TryingAppDelegate

@synthesize window;
@synthesize winController;

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

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

    [self.winController release];
}

@end

и теперь, когда я минимизировать window, Он пошлет -windowDidMiniaturize: сообщение WindowController. Я правильно понял?

если да, то почему бы вам просто не подкласс NSWindow вместо того, чтобы беспокоиться о дополнительном классе, о котором вы должны заботиться?

1 ответов


делегаты особенно полезны, когда вы хотите, чтобы один объект координировал несколько других. Например, вы можете создать NSWindowController подкласс и сделать его делегатом окна. Это же окно может содержать несколько других элементов (например,NSTextFields), который вы хотите сделать контроллером окна делегатом. Таким образом вам не надо подкласс окна и несколько ее элементов. Вы можете сохранить весь код, который концептуально принадлежит одному классу. Кроме того, делегаты обычно относятся к уровню контроллера концепции Model-View-Controller. По подклассам NSWindow вы переместите код типа контроллера на уровень представления.

класс может принять любое количество протоколов, поэтому <NSWindowDelegate, NSTextFieldDelegate> вполне допустимо. Затем вы можете установить объект в качестве делегата любого количества окон и текстовых полей. Чтобы узнать, какие сообщения делегата класс, как NSTextField поддержка проверить ссылка на класс.The -delegate и -setDelegate: методы обычно укажу вам правильный протокол. В нашем случае это NSTextFieldDelegate. Для классов, которые были добавлены в более старую версию фреймворков Apple, часто существует дополнительный раздел о методах делегирования (либо наряду с "методами класса" и "методами экземпляра", либо в качестве подраздела "задачи"). Обратите внимание, что объявление вашего класса в соответствии с протоколом делегата не будет магически доставлено на ваш объект – вы должны явно установить его как делегат:

@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 и AppDelegate просто разные именования одного и того же типа класса.