Розширення класу проти категорії класу


82

Розширення класу @interface Class () набагато потужніші і можуть вводити змінні в клас. Категорії @interface Class (Category)не можуть.

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


категорії - це фактичний код. це те, як ви додаєте функції до класу. розширення - це (у загальних рисах) більше просто синтаксичний цукор, щоб сигналізувати про певні ідеї щодо конфіденційності тощо іншим програмістам. розширення не містять коду і не є кодом.
Fattie

Для розширення , оскільки вони використовуються в Swift, побачити це питання: stackoverflow.com/questions/24142829 / ...
Suragch

Відповіді:


91

Основна відмінність полягає в тому, що з розширенням компілятор очікуватиме, що ви впровадите методи в межах вашого основного @implementation, тоді як для категорії у вас є окремий @implementationблок. Отже, ви повинні в основному використовувати лише розширення у верхній частині вашого основного .mфайлу (єдине місце, яке, до речі, має вас турбувати про ivars) - воно має бути саме таким, розширенням .


41
Розширення найкраще підходить для приватних методів, які ви хочете оголосити у своєму .mфайлі. Я використовую це для цього весь час. Категорії більш корисні, коли ви хочете згрупувати свої методи в різні розділи - категорії :) - або коли ви хочете додати код до існуючих класів, які ви не створили.
jtbandes

1
Ви також можете додати додаткове сховище розширень класу за допомогою властивостей.
Пол.

23
Розширення класів також були спеціально розроблені, щоб дозволити власності публічно readonlyта приватно readwrite. Не можна цього робити з категоріями (свідомий вибір дизайну).
bbum

Чому Google використовує категорію для реалізації приватних методів замість розширення? напр. code.google.com/p/gdata-objectivec-client/source/browse/trunk/…
Райан,

extensions вимагає реалізації всіх методів у блоці @implementation, а також забезпечує покращення змінних. Але ми в основному намагаємось застосувати деякі приватні методи замість використання приватних змінних, тому в такому випадку ми віддаємо перевагу категорії замість розширення
Ankit Thakur

29

Розширення класу має певну схожість із категорією, але його можна додати лише до класу, для якого у вас є вихідний код під час компіляції (клас компілюється одночасно з розширенням класу). Методи, оголошені розширенням класу, реалізовані в блоці @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 є необов’язковим, оскільки він є типовим. Можливо, ви хотіли б використовувати його під час повторного оголошення властивості для ясності.


7

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

Приватні оголошення можуть бути у розширеннях класів, що в основному є деякими властивостями, оскільки нам не потрібно оголошувати метод до того, як ми його викликаємо.


"що має бути оголошено в основному блоці реалізації." -> що має бути "реалізовано" в основному блоці реалізації
Фоукс

Дякую, я його змінив.
Джулі Ю

0

розширення ios подібне до розширення класу c #, java абстрактний клас або інтерфейс
ios категорії подібне до розширення класу c #


Java не підтримує методи розширення
деякі користувачі

вибачте! Копіювати-вставити помилку. категорія ios, подібна до розширення класу c #.
Add080bbA

Чи можете ви додати приклад про?
Педро Трухільо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.