Ответ 1
Прежде всего, немного историческая перспектива по теме, от одного из создателей Java. Далее, Wikipedia имеет умеренно полезный раздел в Objective-C протоколах. В частности, поймите, что Objective-C поддерживает как формальные протоколы (которые явно объявлены с ключевым словом @protocol
, эквивалентом интерфейса Java) и неофициальными протоколами (просто один или несколько методов, реализуемых классом, которые могут быть обнаружены с помощью отражения).
Если вы примете формальный протокол (терминология Objective-C для "реализации интерфейса" ), компилятор будет выдавать предупреждения для нереализованных методов, как и следовало ожидать в Java. В отличие от Java (в качестве skaffman), если класс Objective-C реализует методы, содержащиеся в формальном протоколе, считается, что он "соответствует" этому протоколу, даже если его интерфейс не работает, t явно принять его. Вы можете протестировать соответствие протокола в коде (используя - соответствуетToProtocol:) следующим образом:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
ПРИМЕЧАНИЕ. Apple documentation заявляет:
"Этот метод определяет соответствие только на основе формальных объявлений в заголовочных файлах, как показано выше. Он не проверяет, действительно ли реализованы методы, объявленные в протоколе, - это ответственность программистов."
Как и в случае с Objective-C 2.0 (в OS X 10.5 "Leopard" и iOS) формальные протоколы теперь могут определять необязательные методы, а класс соответствует протоколу, если он реализует все требуемые методы. Вы можете использовать ключевые слова @required
(по умолчанию) и @optional
для переключения, должны ли быть реализованы объявления метода, которые следуют должны или , чтобы соответствовать протоколу. (См. Раздел руководства Apple Objective-C 2.0 Programming Language, в котором обсуждается необязательный протокольные методы.)
Дополнительные методы протокола открывают большую гибкость для разработчиков, особенно для реализации делегатов и слушателей. Вместо того, чтобы расширять что-то вроде MouseInputAdapter (что может раздражать, так как Java также является однонаправленным) или реализует много бессмысленных, пустых методы, вы можете принять протокол и реализовать только дополнительные методы, о которых вы заботитесь. С помощью этого шаблона вызывающий абонент проверяет, реализуется ли этот метод перед его вызовом (используя - отвечаетSoSelector) следующим образом:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Если накладные расходы на отражение становятся проблемой, вы всегда можете кэшировать логический результат для повторного использования, но сопротивляться желанию оптимизировать преждевременно.: -)