Нужно ли указывать протокол, если я хочу, чтобы у моего класса был делегат? - PullRequest
1 голос
/ 29 марта 2009

Я новичок в Objective-C и разработке на платформах Apple, но, надеюсь, я смогу сформулировать этот вопрос понятным образом, независимо от того:)

Я хочу проанализировать XML-канал для своего приложения для iPhone, и я решил вместо того, чтобы помещать все методы делегирования из экземпляра NSXMLParser в мой контроллер представления, я бы обернул это внутри класса FeedParser. Прочитав несколько документов и пример кода, я пришел к следующему:

@protocol FeedParserDelegate <NSObject>

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end


@interface FeedParser : NSObject {
    id <FeedParserDelegate> delegate;
}

@property (nonatomic, assign) id <FeedParserDelegate> delegate;

- (id)initWithURL:(NSURL *)url delegate:(id<FeedParserDelegate>)theDelegate;

@end

Simple. Делегаты моего объекта FeedParser просто должны реализовать parserDidLoadEpisodes.

Однако, когда я фактически начал использовать класс FeedParser, использующий NSXMLParser, я понял, что мне не нужно указывать, что FeedParser реализует протокол для NSXMLParser - я мог просто реализовать методы делегата что я хотел сделать что-то с. Я думаю, что я заметил это с другими классами, которые также следуют шаблону делегата, но не всем.

Так почему бы мне не просто не указать формальный протокол для моего FeedParser класса? Было бы отрезать некоторые, возможно, ненужный код. Я предполагаю, что вопрос заключается в следующем: почему я хотел бы создать формальный протокол вместо того, чтобы просто что-то делать, например, просто проверить, реализован ли метод в делегате с respondsToSelector? Только ли так, что компилятор выдаст приятные предупреждения, если требуемый метод делегата не реализован?

Ответы [ 3 ]

6 голосов
/ 29 марта 2009

Протокол, объявленный с помощью @protocol, называется «формальным протоколом». Другой способ сделать это - объявить категорию (набор дополнительных методов) в NSObject, например:

@interface NSObject (FeedParserDelegate)

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end

Затем просто определите этот метод для любого объекта, которым вы хотите быть делегатом анализатора каналов, и оставьте его неопределенным в противном случае. Это называется "неформальный протокол".

Почему есть два пути? Ну, вот подсказка: неофициальные протоколы были первыми. То, что это сводится к тому, что они добавили формальные протоколы, потому что неофициальные не сокращали это. Неформальные протоколы позволяют слишком легко забыть важный метод или попытаться использовать объект в качестве делегата для чего-то, с чем он не предназначен для работы.

Как правило, за счет добавления <FeedParserDelegate> здесь и там, вы можете заставить компилятор выполнить вашу отладку за вас. Компилятор сгенерирует предупреждения для наиболее распространенных ошибок делегатов, что экономит ваше время, если вы сделаете одну из этих ошибок. Почему бы не воспользоваться его полезностью?

2 голосов
/ 29 марта 2009

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

2 голосов
/ 29 марта 2009

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

Ответ - нет, вам не нужно. Но вы должны хотеть. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...