четверг, 30 апреля 2009 г.

30.04.09. Outlets, Delegates.

Outlets

Outlet - переменная экземпляра, с помощью которой устанавливается связь с другим объектом. Эти связи архивируются в nib-файл и восстанавливаются при загрузке nib-файла.

Обычно таким способом связываются объекты-элементы графического интерфейса и необходимые контроллеры, но могут быть связаны и любые объекты, чьи экземпляры представлены в IB.

Delegates and Data Sources

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

Делегирующий класс имеет у себя свойство или outlet с именем delegate.

Также он должен объявить без реализации несколько методов, которые будет реализовывать делегат. Эти методы должны быть объединены в формальный или неформальный (категория NSObject) протокол. Из формального протокола делегат будет обязан реализовать все методы, кроме отмеченных как optional. Из неформального протокола он может реализовывать любые методы.


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


- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename; // NSApplication
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url; // UIApplicationDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; // NSApplication
- (UITableRowIndexSet *)tableView:(NSTableView *)tableView willSelectRows:(UITableRowIndexSet *)selection; // UITableViewDelegate
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame; // NSWindow

Имя обычно включает глаголы: “Should” or “Will” для событий, которые только должны произойти и “Did” or “Has”, которые уже произошли.

Если событие должно произойти, то делегат может на него повлиять, например, вернуть No для сообщения applicationShouldTerminate.

Для произошедших событий сообщения делегатам носят информирующий характер.


- (void) tableView:(NSTableView*)tableView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn; // NSTableView
- (void)windowDidMove:(NSNotification *)notification; // NSWindow
- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame; // UIApplication
- (void)applicationWillBecomeActive:(NSNotification *)notification; // NSApplication

Если имя сообщения содержит Will, но при этом тип возвращаемого значения void, то это значит, что делегат не может повлиять на факт возникновения события, но может подготовить программу к его появлению.

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

Сделать свой объект делегатом можно в IB, соединив outlet`а delegate с экземпляром своего объекта.

Делегирующие объекты не должны увеличивать счетчик ссылок на делегата, т.е. посылать ему retain. Однако клиенты делегирующего объекта должны проверить в каком состоянии находится делегат и послать ему retain.

Пример: пусть у приложения есть контроллер и у окон этого приложения есть контроллер и они являются делегатами соответственно приложения и окна. Тогда найти контроллер окна можно так:

id winController = [[NSApp keyWindow] delegate];

А контроллер приложения так:

id appController = [NSApp delegate];

Комментариев нет:

Отправить комментарий