2013-05-29 4 views
7

вчера коллега спросил, почему мы не должны объявлять метод init (initWith ...: (...)) в протоколе, чтобы заставить внедряющие классы поставлять такой инициализатор. Я был очень удивлен этим вопросом и, по моему мнению, это вздор. Но я не мог найти окончательную причину, но объявление метода init в протоколе приводит к меньшей гибкости для реализаций.Объект c init в протоколе

Не могли бы вы рассказать мне вескую причину, почему в протоколе должен быть или не должен быть метод init?

Спасибо!

ответ

6

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

  • Вы определить протокол,
  • Кто-то реализует свой протокол,
  • Кто-то создает объект, реализующий ваш протокол, и дает его вам, поэтому
  • Вы,, можете вызывать методы своего протокола, не зная их реализации.

Для вызова методов вашего протокола вам необходимо иметь экземпляр объекта, реализующего его. Весь смысл определения протоколов удаляет из вашего кода любые знания о классе, реализующем ваш протокол: если вы знаете, какой класс вы собираетесь получить, вы можете также пропустить протокол и напрямую перейти к классу. Однако, если вы хотите позвонить своему 10, вам нужно либо знать класс, либо кто-то еще должен передать вам объект alloc, на котором еще не был вызван init. Ни одна из альтернатив не является хорошей идеей - первая убивает цель наличия протоколов, а вторая заставляет ваших абонентов иметь дело с частично инициализированными объектами.

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

+0

Может быть, это нормальная практика, если нет ** Кто-то еще ** создает объект, реализующий интерфейс, но ** Вы **? – SeriousBob

+0

@SeriousBob Если вы создаете объект, то знаете его тип вместе со всеми протоколами, которые он реализует. В этом случае больше не требуется знать, что 'init' (или, если на то пошло, какой-либо другой метод) является частью протокола. – dasblinkenlight

+0

Хорошо, почему протокол NSCoding имеет метод initWithCoder:? – SeriousBob

3

Я знаю несколько протоколов в SDK для iOS, которые имеют методы init .... Например, протокол NSCoding имеет - initWithCoder: требуемый метод. Я считаю, что это обычная практика.

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