Расширения классов @interface Class ()
намного мощнее и могут вводить переменные в класс. Категории @interface Class (Category)
не могут.
Какие еще есть различия и когда следует использовать категорию вместо расширения класса?
Расширения классов @interface Class ()
намного мощнее и могут вводить переменные в класс. Категории @interface Class (Category)
не могут.
Какие еще есть различия и когда следует использовать категорию вместо расширения класса?
Ответы:
Основное отличие заключается в том, что с расширением компилятор ожидает, что вы реализуете методы в своем основном @implementation
, тогда как с категорией у вас есть отдельный @implementation
блок. Таким образом, вам следует использовать расширение только в верхней части вашего основного .m
файла (кстати, единственное место, где вы должны заботиться об ivars) - это должно быть просто расширение .
.m
файле. Я использую его для этого все время. Категории более полезны, когда вы хотите сгруппировать свои методы в разные разделы - категории :) - или когда вы хотите добавить код в существующие классы, которые вы не создавали.
readonly
и частным readwrite
. С категориями этого не сделать (сознательный выбор дизайна).
Расширение класса имеет некоторое сходство с категорией, но его можно добавить только к тому классу, для которого у вас есть исходный код во время компиляции (класс компилируется одновременно с расширением класса). Методы, объявленные расширением класса, реализуются в блоке @implementation для исходного класса, поэтому вы не можете, например, объявить расширение класса в классе инфраструктуры, таком как класс Какао или Какао Touch, например NSString.
Синтаксис объявления расширения класса аналогичен синтаксису категории и выглядит следующим образом:
@interface ClassName ()
@end
Поскольку в скобках не указано имя, расширения классов часто называют анонимными категориями.
В отличие от обычных категорий, расширение класса может добавлять в класс свои собственные свойства и переменные экземпляра. Если вы объявляете свойство в расширении класса, например:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
IMHO, лучше рассматривать расширения класса как частный интерфейс к классу. Основной интерфейс (в вашем .h файле) действует как открытый интерфейс, который определяет поведенческий контракт класса с другими классами.
Используйте расширения класса, чтобы скрыть личную информацию
Расширения классов часто используются для расширения открытого интерфейса дополнительными частными методами или свойствами для использования в реализации самого класса. Например, часто определяют свойство как только чтение в интерфейсе, но как чтение и запись в расширении класса, объявленном над реализацией, чтобы внутренние методы класса могли напрямую изменять значение свойства.
Например, класс XYZPerson может добавить свойство uniqueIdentifier, предназначенное для отслеживания такой информации, как номер социального страхования в США.
Обычно требуется большое количество документов, чтобы присвоить уникальный идентификатор человеку в реальном мире, поэтому интерфейс класса XYZPerson может объявить это свойство как доступное только для чтения и предоставить некоторый метод, который запрашивает присвоение идентификатора, например:
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
Чтобы класс XYZPerson мог изменять свойство внутри, имеет смысл повторно объявить свойство в расширении класса, которое определено в верхней части файла реализации для класса:
@property (readwrite) NSString *uniqueIdentifier;
Примечание. Атрибут readwrite не является обязательным, поскольку он установлен по умолчанию. Вы можете использовать его при повторном объявлении собственности для ясности.
Категории - это функция языка Objective-C, которая позволяет добавлять новые методы в существующий класс. Расширения - это особый случай категорий, которые позволяют определять методы, которые должны быть реализованы в основном блоке реализации.
Частные объявления могут быть в расширениях класса, которые в основном представляют собой некоторые свойства, потому что нам не нужно объявлять метод перед его вызовом.
Расширение ios похоже на C #, абстрактный класс java или интерфейс
категории ios аналогично расширению класса C #