Когда я попытался скомпилировать это под 10.6 с помощью gcc 4.2.1
, он скомпилировал следующее предупреждение:
main.m:12: warning: class 'ITunesFinder' does not implement the 'NSNetServiceBrowserDelegate' protocol
Я подозреваю, что это та же проблема, которую вы описываете, но с более описательной диагностикой, исходящей от компилятора (может быть, более свежая версия, чем у вас?). Вы можете устранить это предупреждение, добавив протокол в объявление интерфейса в заголовке:
@interface ITunesFinder : NSObject<NSNetServiceBrowserDelegate>
Причина, по которой было выдано предупреждение, заключается в том, что метод setDelegate:
имеет следующую подпись:
- (void)setDelegate:(id <NSNetServiceBrowserDelegate>)delegate;
, что просто означает, что он может принимать любой объект, реализующий формальный протокол NSNetServiceBrowserDelegate
. Так как ваш интерфейс класса явно не объявил это, компилятор предупреждает вас об этом. Он все еще должен работать во время выполнения, при условии, что фактические методы предоставляются, когда сообщения делегата действительно отправляются.
возможно ли написать этот пример без использования класса делегата?
Нет, класс делегатов - это способ получения уведомлений о событиях.
Я также немного смущен реализацией класса, книга не описывает, на чем это основано, или, в этом отношении, что делают Категории, Протоколы или Делегаты, и как они работают.
Протокол NSNetServiceBrowserDelegate
определяет набор методов, которые должен реализовать ваш класс. Вы можете думать об этом как об интерфейсе в Java или виртуальном базовом классе в C ++. Разница в Objective-C (который не поддерживает множественное наследование) состоит в том, что вы не наследуете от интерфейса, который пытаетесь реализовать, вы просто объявляете тот факт, что ваш конкретный класс реализует эти методы в соответствии с протоколом.
Теперь протоколы используются для разных целей, и в Какао очень распространенным является использование их для обратных вызовов. Итак, ваш ITunesFinder
реализует протокол браузера таким образом, что NSNetServiceBrowser
знает, как вызывать ваш класс (которого он никогда раньше не видел!), Чтобы предоставлять уведомления браузера.
Эти делегаты часто используются для делегирования поведения от базового класса одному из ваших классов, чтобы позволить вам легко настраивать вещи без большого количества подклассов, и получать уведомления о событиях (обычно до и после чего-то интересного). Это очень элегантная модель.
Документация Apple на эту тему очень хороша: