Что такое делегат в Какао и почему я должен его использовать? - PullRequest
11 голосов
/ 07 октября 2011

Я сейчас пытаюсь выучить Какао, и я не уверен, правильно ли я это понимаю ... Это о делегатах и контроллерах .

Сначала: в чем разница между двумя? Иногда я вижу код, в котором класс называется 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 Ответ

7 голосов
/ 07 октября 2011

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

Класс может принять любое количество протоколов, поэтому <NSWindowDelegate, NSTextFieldDelegate> совершенно допустимо.Затем вы можете установить свой объект в качестве делегата любого количества окон и текстовых полей.Чтобы узнать, какие сообщения-делегаты поддерживает класс, подобный NSTextField, обратитесь к справочнику о классе . Методы -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 - это просто разные именаусловные обозначения для однотипных классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...