Вопрос

Кто-нибудь может объяснить различия между Протоколы и Категории в Objective-C?Когда вы используете одно поверх другого?

Это было полезно?

Решение

Протокол - это то же самое, что и интерфейс в Java:по сути, это контракт, в котором говорится, "Любой класс, который реализует этот протокол, также будет реализовывать эти методы".

Категория, с другой стороны, просто привязывает методы к классу.Например, в Какао, я могу создать категорию для NSObject это позволит мне добавить методы к NSObject класс (и, конечно же, все подклассы), даже несмотря на то, что на самом деле у меня нет доступа к NSObject.

Подводя итог: протокол определяет, какие методы будет реализовывать класс;категория добавляет методы к существующему классу.

Таким образом, правильное использование каждого из них должно быть ясным: Используйте протоколы для объявления набора методов, которые должен реализовать класс, и используйте категории для добавления методов в существующий класс.

Другие советы

Протокол гласит: "вот несколько методов, которые я бы хотел ты для реализации". Категория гласит: "Я расширяю функциональность этого класса с помощью этих дополнительных методов".

Теперь я подозреваю, что ваша путаница проистекает из использования Apple словосочетания "неофициальный протокол".Вот ключевой (и самый запутанный) момент:неофициальный протокол на самом деле вовсе не протокол.На самом деле это категория в NSObject.Cocoa широко использует неофициальные протоколы для предоставления интерфейсов делегатам.С тех пор, как @protocol синтаксис не допускал необязательных методов до Objective-C 2.0, Apple реализовала необязательные методы, которые ничего не делали (или возвращали фиктивное значение), и требовала методы для создания исключения.Не было никакого способа обеспечить выполнение этого через компилятор.

Теперь, с Objective-C 2.0, @protocol синтаксис поддерживает @optional ключевое слово, помечающее некоторые методы в протоколе как необязательные.Таким образом, ваш класс соответствует протоколу до тех пор, пока он реализует все методы, помеченные как @required.Компилятор также может определить, реализует ли ваш класс все необходимые методы, что значительно экономит время.iPhone SDK использует исключительно Objective-C 2.0 @protocol синтаксис, и я не могу придумать веской причины не использовать его ни в одной новой разработке (за исключением приложений Cocoa для Mac OS X, которые должны запускаться в более ранних версиях Mac OS X).

Категории:

Категория - это способ добавления новых методов ко всем экземплярам существующего класса без изменения самого класса.

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

Допустим, вы используете NSView объекты в cocoa, и вы обнаруживаете, что хотите, чтобы все экземпляры NSView смогли выполнить какое-то действие.Очевидно, что вы не можете переписать NSView класс, и даже если вы производны от него, не все NSView объекты в вашей программе будут иметь ваш производный тип.Решение состоит в том, чтобы создать категорию на NSView, который вы затем используете в своей программе.До тех пор, пока ты #import заголовочный файл, содержащий объявление вашей категории, будет выглядеть так, как будто каждый NSView объект реагирует на методы, которые вы определили в исходном файле каталога.

Протоколы:

Протокол - это набор методов, которые любой класс может выбрать для реализации.

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

Это может быть полезно при создании семейства похожих классов, которые все должны взаимодействовать с общим классом "controller".Связь между классом контроллера и управляемыми классами может быть упакована в единый протокол.

Боковое примечание:язык objective-c не поддерживает множественное наследование (класс может быть производным только от одного суперкласса), но большая часть той же функциональности может предоставляться протоколами, поскольку класс может соответствовать нескольким различным протоколам.

Насколько я понимаю, протоколы немного похожи на интерфейсы Java.Протоколы объявляют методы, но реализация зависит от каждого класса.Категории, похоже, представляют собой что-то вроде миксинов Ruby.С помощью категорий вы можете добавлять методы к существующим классам.Даже встроенные классы.

Протокол позволяет вам объявить список методов, которые не ограничены каким-либо конкретным классом или категориями.Методы, объявленные в протоколе, могут быть приняты любым классом /категориями.Класс или категория, которые принимают протокол, должны реализовывать все требуемые методы, объявленные в протоколе.

Категория позволяет вам добавлять дополнительные методы к существующему классу, но они не допускают дополнительных переменных экземпляра.Методы, добавляемые категорией, становятся частью типа класса.

Протоколы - это контракты на реализацию указанных методов.Любой объект, соответствующий протоколу, соглашается предоставить реализации для этих методов.Хорошим использованием протокола было бы определить набор методов обратного вызова для делегата (где делегат должен отвечать на все методы).

Категории предоставляют возможность расширить текущий объект путем добавления к нему методов (методов класса или экземпляра).Хорошим применением для категории было бы расширение класса NSString для добавления функциональности, которой раньше не было, например, добавление метода для создания новой строки, которая преобразует receiver в 1337 5P34K.

NSString *test = @"Leet speak";
NSString *leet = [test stringByConvertingToLeet];

Определения из книги С.Г. Кочана "Программирование на Objective-C":

Категории:

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

Протоколы:

Протокол - это список методов, который является общим для всех классов.Методы, перечисленные в протоколе, не имеют соответствующих реализаций;они предназначены для реализации кем-то другим (например, вами!).Протокол предоставляет способ определения набора методов, которые каким-то образом связаны с указанным именем.Методы обычно документированы, чтобы вы знали, как они должны выполняться, и чтобы при желании вы могли реализовать их в своих собственных определениях классов.Протокол содержит список методов, некоторые из которых вы можете реализовать при необходимости, а другие - те, которые от вас требуется реализовать.Если вы решите внедрить все необходимые методы для определенного протокола, считается, что вы соответствуете этому протоколу или принимаете его.Вам разрешается определить протокол, в котором все методы являются необязательными, или тот, в котором все они обязательны.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top