Подтвердить что ты не робот

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

В настоящее время я пытаюсь изучить 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 вместо того, чтобы беспокоиться о дополнительном классе, о котором вы должны заботиться?

4b9b3361

Ответ 1

Делегаты особенно полезны, когда вы хотите, чтобы один объект координировал несколько других. Например, вы можете создать подкласс 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 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 - это просто разные соглашения об именах для одного и того же типа.