Есть ли разница между <NSXMLParserDelegate>, только методом setDelegate или использованием обоих? - PullRequest
1 голос
/ 20 февраля 2010

Я заметил, что когда я делаю это:

[myParser setDelegate:self];

это работает: D (даже если я не добавил код в заголовочный файл ... вы знаете,

<delegateStuff, delegateOtherStuff> 

в объявлении интерфейса)

Когда вы должны изменить заголовочный файл, чтобы ваш делегат работал? Достаточно ли метода setDelegate, чтобы он работал?

Ура за любую помощь;)

Готье

Ответы [ 4 ]

1 голос
/ 20 февраля 2010

Короче говоря, <NSXMLParserDelegate> в объявлении интерфейса не требуется , оно существует для проверки ошибок во время компиляции. Вызов setDelegate: метода необходим , если вы хотите получать сообщения делегатов.

<delegateStuff>, на которую вы ссылаетесь, является объявлением протокола. Протокол в Objective-C подобен интерфейсу в Java: он определяет список сообщений (методов), на которые отвечает класс. Однако, в отличие от Java, Objective-C имеет динамическую типизацию, что означает, что любое сообщение может быть отправлено любому объекту, и вы можете быть уверены только в том, что оно ответит на него во время выполнения.

Результатом этого является то, что если метод, подобный setDelegate:, запрашивает параметр типа id, вы можете присвоить ему любой объект. Код в NSXMLParser может проверить, может ли он ответить на конкретное сообщение перед его отправкой. Таким образом, вы можете реализовать любые методы делегирования, которые вы хотите. (Поскольку Java имеет более строгую проверку типов, вы должны реализовать все методы в интерфейсе, нужны они вам или нет.)

Если setDelegate: вместо этого действует для типа id <NSXMLParserDelegate>, то теперь он говорит, что ему нужен объект, реализующий протокол NSXMLParserDelegate. Это проверяется только во время компиляции, чтобы помочь вам отлавливать ошибки. Если вы используете Typecast, вы можете отправить туда любой объект, и, пока он отвечает на требуемые сообщения, ваша программа будет работать нормально. (Опять же, в Java вы можете использовать трансляцию типов для компиляции, но сама трансляция типов выдает исключение, если объект имеет неправильный тип, даже если он имеет те же методы.)

Кстати, вы подкласс NSXMLParser? (Я так полагаю, поскольку вы передаете self в setDelegate:. Это не тот способ, которым он предназначен для использования! Каркасы Какао обычно предпочитают делегатов над подклассами. Ваш класс делегата должен быть отдельный класс, расширяющий NSObject (или что-то еще, если хотите).

1 голос
/ 31 мая 2010

Компилятор теперь предупреждает, если отсутствует в iPhone SDK 4.0

1 голос
/ 20 февраля 2010

Когда это потребуется, компилятор сообщит вам с предупреждением.

Я заметил, что когда вы добавляете файл заголовка, XCode может автоматически завершать любые методы делегатов, которые вы можете использовать. Я делаю это каждый раз только по этой причине.

0 голосов
/ 18 июня 2010

«Делегат» всегда будет работать до тех пор, пока он реализует селекторы, которые вызываются во время выполнения. Объявление соответствующего протокола делегирования не требуется, но вы можете получить предупреждение компилятора, если делегат набран не только как «id» (например, id [SomeDelegateProtocol] делегат).

Однако ... если вы объявите, что класс соответствует спецификации определенного протокола, то (а) этот протокол должен существовать и (б) ваш класс будет проверен на селекторы протоколов. NSXMLParserDelegate, который теперь включен в iPhone SDK 4, заставит старые приложения выдавать предупреждение; если вы добавите протокол, а затем попытаетесь выполнить обратную компиляцию в 3.x, вы получите ошибку компиляции, поскольку протокол не существует до 4 (по крайней мере, вы вряд ли включили в него фреймворк с этим протоколом). Я только что столкнулся с этим, когда начинаю переносить текущие приложения с 3 на 4. Я ненавижу предупреждения, которые я не могу легко устранить.

...