Расширение класса vs категория класса

расширения-класс @interface Class () гораздо более мощные, и могут вводить переменные в классе. Категории @interface Class (Category) Не могу.

какие еще существуют различия и когда следует использовать категорию над расширением класса?

4 ответов


основное отличие заключается в том, что с расширением компилятор ожидает, что вы реализуете методы в своем main @implementation, тогда как с категорией, у вас есть отдельная @implementation заблокировать. Таким образом, вы должны в значительной степени использовать расширение только в верхней части вашего main .m файл (единственное место, где вы должны заботиться о ivars, кстати) - это должно быть именно это,расширение.


расширение класса имеет некоторое сходство с категорией, но его можно добавить только к классу, для которого у вас есть исходный код во время компиляции (класс компилируется одновременно с расширением класса). Методы, объявленные расширением класса, реализованы в блоке @implementation для исходного класса, поэтому вы не можете, например, объявить расширение класса в классе framework, таком как класс Cocoa или Cocoa Touch, такой как NSString.

синтаксис для объявления расширение класса аналогично синтаксису для категории и выглядит следующим образом:

@interface ClassName ()
@end

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

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

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

IMHO, лучше всего думать о расширениях классов как о частном интерфейсе для класс. Основной интерфейс (в вашем .H file) действует как открытый интерфейс, который определяет поведенческий контракт класса с другими классами.

используйте расширения классов, чтобы скрыть личную информацию

расширения класса часто используются для расширения открытого интерфейса дополнительными частными методами или свойствами для использования в реализации самого класса. Обычно, например, определить свойство как readonly в интерфейсе, но как readwrite в расширении класса, объявленном выше реализации, чтобы внутренние методы класса могли напрямую изменять значение свойства.

в качестве примера класс XYZPerson может добавить свойство uniqueIdentifier, предназначенное для отслеживания информации, такой как номер социального страхования в США.

обычно требуется большое количество документов, чтобы иметь уникальный идентификатор, назначенный человеку в реальном мире, поэтому класс XYZPerson интерфейс может объявить это свойство как readonly и предоставить некоторый метод, который запрашивает присвоение идентификатора, например:

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

чтобы класс XYZPerson мог изменять свойство внутренне, имеет смысл повторно объявить свойство в расширении класса, которое определено в верхней части файла реализации для класса:

@property (readwrite) NSString *uniqueIdentifier;

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


категории-это функция языка Objective-C, которая позволяет добавлять новые методы в существующий класс. Расширения-это особый случай категорий, которые позволяют определить методы, которые должны быть реализованы в основном блоке реализации.

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


iOS расширение, похожее на c#, Java абстрактный класс или интерфейс
категория ios похожа на расширение класса c#