Подтвердить что ты не робот

Можно ли наследовать протоколы и категории Objective-C?

Я немного смущен некоторыми понятиями вокруг Objective-C протоколов и категорий.

Могут ли протоколы и категории наследоваться подклассами в Objective-C?

4b9b3361

Ответ 1

Категории представляют собой коллекции методов, которые добавляются в класс во время выполнения. Поскольку Objective-C использует динамическое связывание, это означает, что методы, определенные в категории, доступны для класса и всех его подклассов. В частности, селекторы привязаны к методам в точке, где они вызывается, а не во время компиляции или когда программа загружается первой. Категории добавляются в классы, когда они (категории) загружаются.

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

Протоколы могут быть расширены для создания новых протоколов. состоящий из надмножества методов в исходном протоколе. Фактически, так же, как большинство классов наследует класс NSObject, большинство протоколов расширяют протокол NSObject (имена протоколов и имена классов находятся в разных пространствах имен). Это значит, что объектам, объявленным как id<WhateverProtocol>, могут быть отправлены базовые сообщения, такие как -retain, -release и т.д., Не генерируя предупреждения компилятора.

Ответ 2

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

В то время как протокол представляет собой список методов, которым требуется класс, который подтверждает его, чтобы реализовать все это (если он не использует тег @optional). Таким образом, нет смысла подзадача этого класса.

Edit:

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

Ответ 3

Твой вопрос непонятен. Возможно, вы спрашиваете, наследуют ли подклассы протоколы и категории своего суперкласса. @theAmateurProgrammer ответил на это.

Вы также можете спросить, могут ли сами категории и протоколы наследовать другие категории и протоколы. Для категорий ответ - нет. Для протоколов ответ да, и на самом деле протоколы должны почти всегда наследоваться так же, как и классы:

@protocol SomeProtocol <NSObject>
...
@end

Это говорит о том, что все, что соответствует <SomeProtocol>, также соответствует <NSObject> (который является протоколом, а также классом). Это позволяет вам вызывать методы типа respondsToSelector:, что очень важно для большинства реализаций протокола.

Ответ 4

Протоколы как интерфейсы в Java. Таким образом, класс предоставляет протокол для доступа к нему.

Вы можете "подклассировать" протоколы так же, как в Java, вы можете "подклассировать" интерфейсы.

С другой стороны, категории - это способ добавить к классу дополнительные методы. Ограничение: вы не можете добавлять переменные экземпляра с категорией. Вы можете получить доступ только к существующим переменным экземпляра.

Это очень полезно, хотя из-за того, что он избегает создания большой хрупкой иерархии подкласса.

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

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

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

Ответ 5

NSObject соответствует протоколу NSObject

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

Скажем, что у нас есть подкласс NSObject

@interface FTGAnimal : NSObject

@end

@implementation FTGAnimal

@end

Мы видим, что FTGnimal фактически соответствует протоколу NSObject

if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) {
        NSLog(@"FTGAnimal conforms to NSObject protocol");
}