Это ключевая концепция для концептуального понимания, поэтому важно подумать над тем, как думать об этом, прежде чем приступить к техническим деталям. Проще говоря, делегат является обратным вызовом.
Два основных сценария использования делегатов:
- Класс или элемент управления хотят абстрагироваться от деталей о том, как выполнять работу (например, извлекать данные).
- Разрешить другим подключать код к конвейеру.
Примеры:
UITableView - табличное представление - это просто элемент управления, который знает, как отобразить список ячеек. Он обрабатывает все тяжелые операции рендеринга, прокрутки и т. Д. Но он не знает, как загрузить ваши данные. Таким образом, вы реализуете делегат источника данных, который имеет методы для получения данных ячейки для данной строки и т. Д. Это облегчает вам задачу. Вы просто используете элемент управления и вставляете данные для своих данных. UITableView сделает все за вас ... просто ответьте на несколько конкретных вопросов. Делегат отвечает на эти несколько конкретных вопросов.
Текстовый элемент управления - вы добавляете текстовый элемент управления для вашего представления и вуаля! Вы можете ввести его и все хорошо. Но что, если вы захотите что-то сделать, когда они начнут печатать или когда они закончат печатать? Ну, текстовый элемент управления предлагает делегат с методами, которые позволяют вам подключиться к конвейеру выполнения текстового элемента управления. Он позволяет текстовому управлению делать все за вас и позволяет вставлять код там, где он вам нужен. Много раз, есть способ вставить код, чтобы принять решение о том, разрешено ли что-то. Управление перезвонит и спросит, могу ли я сделать х? Вы можете вставлять код и влиять на поведение.
Если вы создаете элемент управления или класс, вы можете создать свой собственный протокол, делегатов источника данных и т. Д. ... так что ваш элемент управления может сосредоточиться на том, что рекламируется. Например, допустим, вы хотите создать элемент управления задачами. Вы могли бы:
Сначала создайте договор. Эй, если вы собираетесь предоставить данные для моего контроля, вот вопросы, которые я собираюсь вам задать. Я возьму это оттуда ... В этом случае я собираюсь спросить вас о количестве заданий, и я собираюсь попросить вас дать мне задание, учитывая номер строки.
@protocol XXTaskBoardDelegate <NSObject>
-(NSInteger*)getTaskCount;
-(XXTask*)getTaskForRow:(NSInteger*)rowNumber;
@end
В элементе управления или классе предоставьте потребителю способ предоставить нам класс источника данных делегата, который будет отвечать на вопросы, которые задает элемент управления. На данный момент контроль является чистым контролем. Он ничего не знает о том, как вы получаете ваши данные. Он запрашивает объект (id), который реализует контракт / протокол. ID
@implementation XXTaskBoard
- (void)setDelegate:(id<XXTaskBoardDelegate>)newDelegate
{
// the control stores the delegate so it can callback and ask you questions.
}
Затем для класса делегата в заголовке объявите, что вы реализуете этот формальный протокол.
и в файле реализации m вы предоставляете код.
@interface AppController : NSObject<XXTaskBoardDelegate>
{
//...
}
затем внедрите его в реализацию
@implementation AppController
- (NSInteger*)getTaskCount
{
return [model queryTaskCount];
}
- (XXTask*)getTaskForRow:(NSInteger*)rowNumber
{
return [[model tasks] getItem:(NSInteger*)rowNumber];
}