Розширення класу @interface Class ()
набагато потужніші і можуть вводити змінні в клас. Категорії @interface Class (Category)
не можуть.
Які ще відмінності існують, і коли слід використовувати категорію над розширенням класу?
Розширення класу @interface Class ()
набагато потужніші і можуть вводити змінні в клас. Категорії @interface Class (Category)
не можуть.
Які ще відмінності існують, і коли слід використовувати категорію над розширенням класу?
Відповіді:
Основна відмінність полягає в тому, що з розширенням компілятор очікуватиме, що ви впровадите методи в межах вашого основного @implementation
, тоді як для категорії у вас є окремий @implementation
блок. Отже, ви повинні в основному використовувати лише розширення у верхній частині вашого основного .m
файлу (єдине місце, яке, до речі, має вас турбувати про ivars) - воно має бути саме таким, розширенням .
.m
файлі. Я використовую це для цього весь час. Категорії більш корисні, коли ви хочете згрупувати свої методи в різні розділи - категорії :) - або коли ви хочете додати код до існуючих класів, які ви не створили.
readonly
та приватно readwrite
. Не можна цього робити з категоріями (свідомий вибір дизайну).
Розширення класу має певну схожість із категорією, але його можна додати лише до класу, для якого у вас є вихідний код під час компіляції (клас компілюється одночасно з розширенням класу). Методи, оголошені розширенням класу, реалізовані в блоці @implementation для оригінального класу, тому ви не можете, наприклад, оголосити розширення класу у фреймворковому класі, такому як клас Cocoa або Cocoa Touch, такий як NSString.
Синтаксис для оголошення розширення класу подібний до синтаксису категорії і виглядає так:
@interface ClassName ()
@end
Оскільки в дужках не вказано імені, розширення класів часто називають анонімними категоріями.
На відміну від звичайних категорій, розширення класу може додавати власні властивості та змінні екземпляра до класу. Якщо ви оголошуєте властивість у розширенні класу, ось так:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
ІМХО, найкраще розглядати розширення класів як приватний інтерфейс класу. Первинний інтерфейс (у вашому файлі .h) діє як загальнодоступний інтерфейс, який визначає поведінковий контракт класу з іншими класами.
Використовуйте розширення класів, щоб приховати приватну інформацію
Розширення класів часто використовуються для розширення загальнодоступного інтерфейсу додатковими приватними методами або властивостями для використання в рамках реалізації самого класу. Наприклад, зазвичай властивість визначати властивість як readonly в інтерфейсі, але як readwrite у розширенні класу, оголошеному над реалізацією, для того, щоб внутрішні методи класу могли безпосередньо змінювати значення властивості.
Як приклад, клас 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 #