Обновление: делегаты не обязаны соответствовать протоколам. Протоколы просто упрощают требование, чтобы у некоторых классов были методы. Он позволяет вам наверняка знать, что объект, установленный в качестве делегата, реализует определенный метод, чтобы вы могли его безопасно вызывать, и позволяет компилятору проверить, действительно ли реализован этот метод (если вы объявляете переменную экземпляра делегата как id<SomeProtocol> delegate
, компилятор выдаст предупреждение или ошибку, если вы попытаетесь установить delegate
для объекта класса, который не соответствует SomeProtocol
.
Протоколы помогают обеспечить безопасность, но они не являются строго необходимыми. У класса может быть делегат (или несколько!), И они вообще не обязаны соответствовать каким-либо протоколам.
Что касается выходов, нет, они используются специально и только с Interface Builder. Ключевые слова IBOutlet
и IBAction
не влияют на код (они даже удаляются перед компиляцией) - они всего лишь маркеры, которые должен искать Interface Builder, чтобы он знал, какие свойства и методы должны быть доступны в интерфейсе. Термин «выход» - это прямая ссылка на что-то, помеченное как IBOutlet
, и на самом деле не используется в каком-либо другом контексте, который я могу сказать.
Опять же, ничего страшного, если вы этого не поймете сразу. Подумайте немного, и в какой-то момент он просто «щелкнет». Я был занят делегатами в течение долгого времени, точно так же, прежде чем однажды я понял, что делегаты на самом деле не особенные. Это обычные объекты, на которые ссылаются другие объекты - просто у этого шаблона проектирования есть специальное имя (делегирование), и эти объекты только называются делегатами. Их так же легко можно было бы назвать gyros
или falafels
, и чистый эффект был бы таким же. : P
Вам не нужно называть объект delegate
, чтобы он был делегатом; это просто условность.
О делегатах: первое, что нужно понять, и это помогло мне на время, пока я не услышал правильное «Ага!» Момент заключается в том, что в «делегате» нет ничего особенного. Слово «делегат» - это просто название типа объекта, от которого зависит другой класс, очень часто для содержания или принятия решений. Разработчик будет использовать делегата, когда он не хочет (или не может) связывать один из своих классов с другим классом по имени - это объектно-ориентированный способ разделения и создания классов более универсальными.
Теперь очень часто классы требуют, чтобы у делегатов были определенные методы, на которые они полагаются, и один из способов гарантировать это - с помощью протокола (более известного как интерфейс в Java). Протоколы определяют список методов; классы «соответствуют» протоколу, если они декларируют это в своем интерфейсе (например, @interface IFObject : NSObject <SomeProtocol> { ... }
) и если они реализуют все методы, которые им необходимы. Протоколы также могут иметь дополнительные методы.
Эта модель часто используется с контроллерами представлений, представлениями и графическим интерфейсом пользователя в целом, потому что многие классы AppKit и UIKit написаны как можно более общими. NSTableView
, например, реализует самое базовое поведение, которое он может реализовать, не требуя какой-либо информации, зависящей от реализации; в остальном он полагается на другие объекты, соответствующие протоколам NSTableViewDelegate
и NSTableViewDataSource
. Любой объект может соответствовать протоколам, если они реализуют правильные методы (и в этом случае класс контроллера обычно реализует методы из обоих протоколов, но это не обязательно так) . Фактически, один из простых способов лучше понять эту тему - взглянуть на NSTableView
- у него есть свойство delegate
и свойство dataSource
, но, по сути, они ничем не отличаются. delegate
можно было бы назвать monkeyButt
, и концепция все равно работала бы. Главное - не относиться к делегатам как к черному ящику - в них нет ничего особенного.
Делегаты также могут использоваться для целей, не связанных с графическим интерфейсом пользователя; один конкретный пример, как вы упомянули, - это делегат приложения. NSApplication
отправляет уведомления делегату, чтобы сообщить ему, когда приложение было запущено (среди прочего), чтобы он мог настроить магазин. Опять же, любой объект может быть делегатом любого другого объекта для любой цели. Это просто условность.
Вкратце о выходах: как уже упоминалось, выходы - это просто соединения между интерфейсом, определенным в XIB, и вашим кодом. Это способ позволить Xcode связать интерфейс с соответствующими элементами, чтобы, когда ваше приложение загружает файл интерфейса, оно могло загружать нужные фрагменты кода или выполнять их.
Как правило, они представляют собой более простой способ настройки интерфейса - они не являются строго необходимыми (вы можете создать интерфейс программно, без использования файла XIB), но если вы решите пойти по маршруту XIB, они помогут вам свяжите ваш интерфейс с вашим кодом.
person
Itai Ferber
schedule
22.01.2013