2009-08-28 2 views
12

Я знаю хороший объект Objective-C, и я работаю над книгой iPhone SDK (из книги Obj-C, которая только что делала консольные программы). Он попытался объяснить делегатов, хотя он был брошен и на самом деле не понимал, что он пытался передать. Я немного смущен тем, что они есть, и когда вы будете их использовать.Немного запутался в делегатах в Objective-C

В целом, он сказал, что это классы, которые несут ответственность за выполнение определенных действий от имени другого объекта.

Кто-нибудь заботится о разработке?

Спасибо!

+2

Мне было трудно с этим, когда я начинал смотреть на Какао. Ты не одинок. – jergason

ответ

6

Хороший способ понять делегатов - это пример. Одним из примеров является UITableView (или NSTableView, в зависимости от того, говорим ли мы на iPhone или Mac OS). В любом случае табличный вид имеет delegate и dataSource (оба из которых действуют как вспомогательные объекты на ресивер).

Вместо UITableView обработка событий, когда один из его строк прослушивается пользователем, вместо этого он сообщает его delegate «Эй, я был использован в этой строке и в этом разделе, сделай то, что будешь! ». Обычно delegate является контроллером какого-то типа, который реализует правильный метод. Таким образом, представление таблицы (после проверки, чтобы увидеть, если delegate на самом деле имеет определение для метода) посылает сообщение, как это:

[delegate tableView:self didSelectRowAtIndexPath:indexPath]; 

Поскольку ваш контроллер делегат таблицы, и он реализует этот метод, он решает, что делать. Когда метод завершится (в этом случае он должен просто вернуть void), то выполнение продолжается в представлении таблицы.

Делегаты - это концепция. Это не языковая особенность Objective-C. Элемент UITableView delegate похож на любой другой объект. Хотя делегаты, как правило, не сохранены, они вместо этого назначены (чтобы избежать retain циклов).

Они очень удобны, когда вы получаете их. Я предлагаю практиковать с примерами, такими как TableViews (NSTableView, как я уже говорил ранее, работает аналогичным образом, используя разные методы).

+0

Таким образом, это класс, который Object требует, когда что-то делается для себя. И в зависимости от того, что было сделано для себя, он вызывает определенный метод из класса делегата. Верный? Является ли их надлежащим способом создания класса делегатов, или это просто еще один обычный класс с методами, которые вызовут другие классы? – 2009-08-28 22:55:57

+1

Технически делегат является объектом. У вас может быть пятьдесят экземпляров объекта, который реализует некоторые методы делегата, но только тот экземпляр, который установлен в качестве делегата, вызвал его методы. Правильный способ создания делегата - определить протокол, который определяет набор методов, которые должны/могут быть реализованы. – johnw188

+1

@Avizz: Вы правы, делегат может быть любым желаемым объектом. Хотя обычно это будет «соответствовать протоколу». Если объект соответствует данному протоколу, это в основном означает: «Я обещаю, что я выполнил все, что от меня требуется в данном протоколе». Таким образом, когда объект отправляет сообщение делегату, они уверены, что делегат знает, что делать – jbrennan

7

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

Для того, чтобы класс был делегатом, вы должны объявить его как таковой. В приведенном выше примере скажем, что у вас есть объект ApplicationController, который контролирует поток вашего приложения. В заявлении, мы сказали бы

@interface ApplicationController : NSObject <UIAlertViewDelegate> 

Это говорит компилятору, что ApplicationController собирается реализовать некоторые методы в протоколе UIAlertViewDelegate. Мы смотрим этот протокол в нашей документации и видим список методов. Как мы хотим что-то сделать при нажатии кнопки, мы видим:

alertView:clickedButtonAtIndex: - Отправлено делегату, когда пользователь нажимает кнопку в виде предупреждения. Этот метод является необязательным.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

Таким образом, если мы реализуем метод в ApplicationController называется alertView:clickedButtonAtIndex, создать объект ApplicationController, а затем установить этот объект в качестве делегата предупреждения мы покажем, как все установлено. Как только кто-то нажмет кнопку на предупреждение, вызывается метод alertView:clickedButtonAtIndex, передавая в alertView и индекс нажатой кнопки.

Это позволяет вам делать все, что хотите, с помощью этой информации. Простой случай заявление:

if(buttonIndex == 0) { 
    _myString = @"Pressed the button"; 
} else { 
    _myString = @"Pressed the other button"; 
} 

Ссылочные документы Objective-C очень, очень хорошо, и все протоколы делегата довольно понятны.

+0

что означает символ? –

+1

Это зависит от того, на что вы ссылались. Вы можете определить строки на месте, указав @ "string here", что является объективной c-синтаксической вещью. В противном случае @interface - это объявление класса. Множество объективных c конкретных вещей начинаются с @, так как они никогда не используются в идентификаторах C/C++. Это позволяет разработчикам цели c гарантировать, что нет никакой путаницы в отношении того, что-то из C/C++ или цели c – johnw188

20

Думайте о делегатах как о инверсии направления зависимостей. В большинстве случаев клиенты будут вводить требуемые зависимости в экземпляры, как правило, в конструкторе или сеттерах.

Какао делает обратное; экземпляры вместо этого запрашивают данные, когда и когда это необходимо.

Есть четыре основных типа методов делегата:

  • УСЛОВНО перед тем - Сигналы что-то должно произойти, но делегат может прервать. Имя всегда включает слово Should.
    Пример: searchBarEndEditing:.
  • Безусловно до - Сигналы что-то произойдет. Имя всегда включает слово.
    Пример: applicationWillTerminate:.
  • безоговорочно после - Сигналы что-то произошло. Имя всегда включает слово.
    Пример: applicationDidFinishLaunching:.
  • Настройщики - Запросить информацию о том, как работать. Имя включает информацию, которая требуется.
    Пример tableView:viewForHeaderInSection:.

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

+1

. Лучше всего объяснение среди этих ответов, imho –

2

Делегат (что означает представитель) является объектом класса ('s), который хочет также представлять (наследовать) другой несвязанный класс.Объект делегирования может наследовать от иначе несвязанного класса путем «соответствия» (с некоторыми реализациями) методов протокола не связанных между собой классов, которые указывают иностранному классу, что этот объект теперь способен правильно управлять своей самой базовой информацией.

Вы используете наследование, если вы хотите классы для обмена методами. Вы используете делегатов, если вы хотите не связаны классы для обмена методами. Подход делегата позволяет объекту из одного класса наследовать методы из иначе несвязанного класса. «Объект делегирования» или «представительский объект» - это объект, который наследуется от иностранного класса; он назначается представителем, делегатом этого удаленного класса, поэтому, когда вы назначаете объект в качестве делегата для класса, вы даете ему разрешение также представлять этот класс, даже если он обычно не наследуется от этого класса , (Если он унаследован от класса, тогда вам не нужно будет устанавливать его как делегат этого класса, он уже будет иметь доступ к методам класса. Но вы хотите, чтобы этот несвязанный объект наследовал некоторые методы из класса, представляя это class и возвращать некоторую информацию обратно в класс отправителя, поэтому вы делаете его представителем делегата этого класса, даже если он наследуется от другого набора классов.) Это по существу позволяет одному неродственному классу наследовать от другого несвязанного класса, но с минимум осложнений по отношению к основной линии наследования.

Вы используете систему делегатов, если хотите, чтобы объект выполнял код из отдельного класса. Например, as described here, когда вы нажимаете Enter в текстовом поле, текстовое поле действительно не знает, что делать с этой информацией. То, что он делает, выглядит как класс его делегата (например, оконный контроллер документа или документ) и использует соответствующий метод этого класса, который соответствует соответствующему методу текстового поля, найденному в его протоколе делегирования текстового поля, что-то вроде textFieldShouldReturn. Таким образом, в этом случае вы устанавливаете оконный контроллер или документ в качестве делегата текстового поля, потому что текстовое поле нуждается в этом классе для представления информации, которую он предоставил.

класса А необходим метод из класса B, но класса А не наследует от класса B. Во-первых, сказать компилятору, что класс А соответствует протоколу класса B:

@interface ClassA : NSObject <ClassBDelegateProtocol> 

В документации компании Apple, каждая ссылка класса отображается вверху, «Inherits from» и «Conforms to». Например, NSDocumentController наследует от NSObject и соответствует NSUserInterfaceValidations, NSCoding и NSObject(NSObject). Соответствие NSCoding от декларации интерфейса в NSDocumentController.h

@interface NSDocumentController : NSObject <NSCoding> 

и NSUserInterfaceValidations из декларации метода в NSDocumentController.h

-(BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item; 

вместе с #import

#import <AppKit/NSUserInterfaceValidation.h> 

Так тогда как NSDocumentController наследуется от NSObject, он также нуждается в помощи отNSCoding и NSUserInterfaceValidation. И он получает помощь от этих иностранных классов по в соответствии с их протокольными методами, , определяя себя в соответствии с этими методами и , импортируя необходимые файлы заголовков для использования этих методов.

0

Вы не одиноки, я все еще изучаю это сам. Я думаю, что лучше всего, если я попытаюсь объяснить это словами вместо кода. Существует протокол, который содержит определенный метод или действие, которое вы хотите выполнить. Делегат принимает метод из протокола, поэтому он может использовать его для облегчения действия или метода. Я нашел эту статью очень полезной http://rypress.com/tutorials/objective-c/protocols. Надеюсь это поможет.

Смежные вопросы