Разница между категорией и расширением класса?

85

В чем разница между категорией и расширением класса. Я считаю, что оба используются для добавления пользовательских методов в существующие классы. Может кто-нибудь пролить свет на это? Мы будем очень благодарны за пояснения с кодом.

Абхинав
источник
3
Акусете, страница не найдена.
Адиль Хуссейн,
ясно проиллюстрировано здесь, code.tutsplus.com/tutorials/…
grassyburrito

Ответы:

103

Категория - это способ добавления методов к существующим классам. Обычно они находятся в файлах с именем «Class + CategoryName.h», например «NSView + CustomAdditions.h» (и, конечно, .m).

Расширение класса - это категория, за исключением двух основных отличий:

  1. Категория не имеет названия. Заявлено это так:

    @interface SomeClass ()
    
    
    - (void) anAdditionalMethod;
    
    @конец
  2. Реализация расширения должна находиться в основном блоке @implementation файла.

Довольно часто можно увидеть расширение класса в верхней части файла .m, объявляющее дополнительные методы класса, которые затем реализуются ниже в основном разделе @implementation класса. Это способ объявления «псевдоприватных» методов (псевдо-частных в том смысле, что они не совсем частные, просто не доступны извне).

Дэйв Делонг
источник
13
В Class-Extensiosn вы можете перезаписывать свойства из (общедоступного) свойства, доступного только для чтения, для внутреннего чтения и записи. А начиная с LLVM 1.5 вы можете делать даже больше: теперь вы можете объявлять переменные экземпляра в расширении класса, чтобы они исчезли из обычного интерфейса.
Макс Зелеманн
Зачем добавлять расширение класса, если можно просто реализовать эти методы и свойства прямо в классе? Мне кажется немного лишним.
user1721803
1
@ user1721803 Как предложил Дэйв, вы можете оставить несколько свойств / методов неэкспонированными. Это когда используются расширения. Рассмотрим представление, вы можете подключить все свои IBOutlets и IBActions в расширении и предоставить методы, которые позволяют инициализировать / обновлять выходы, и действия могут быть делегированы обратно.
GoodSp33d
@MaxSeelemann, не могли бы вы продемонстрировать, как сделать «(общедоступное) свойство только для чтения для внутреннего чтения и записи» с помощью короткого скрипта? Спасибо.
allenlinli
В этом ответе указано расширение в файле «Class + CategoryName.swift», это правильно?
Ritesh.mlk
47
  1. Категория

=> В Objective C, когда вы хотите добавить к классу дополнительные функции без наследования, вы просто используете для него категорию.

=> у него есть собственные файлы .h и .m

=> Categoryиспользуется для добавления нового метода, а не свойств.

  1. Расширение класса
-> In Objective C, when you want to make behaviour of some property private you use class extension.

-> it comes with **.h** file only.

-> mainly for properties.

Примечание: когда мы добавляем новый файл и выбираем вариант цели c, категория показывает категорию и «категорию», а не «подкласс», поэтому отображается как

@interface className (categoryName)
@end

-Вы получите два файла .h и .m с именем файла как ( className + categoryName.h и className + categoryName.m )

и в случае продления вы получите

@interface className()
@end

-Вы получите только один файл с именем className_extensionName.h

  • В категории вы не владеете классом, но в расширении вы им являетесь.
Анураг Бхакуни
источник
5
@Prasanna: расширение класса идет только с файлом .m, а не в .h
Saggy
1
расширение class идет только с файлом .h, а не с .m
Nishu_Priya
32
  1. Категория - это способ добавления методов к классу независимо от того, доступен ли исходный код или нет, то есть вы можете добавить категорию к базовым классам, например, NSStringа также к своим собственным настраиваемым классам.

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

  2. Мы можем добавить дополнительные переменные экземпляра и свойства в расширение класса, но не в категорию.

  3. Любая переменная и метод внутри расширения недоступны даже для унаследованных классов.

  4. Категория и расширение в основном созданы для обработки большой базы кода, но категория - это способ расширения API класса в нескольких исходных файлах, а расширение - это способ добавления необходимых методов за пределами основного файла интерфейса.

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

Вену Гопал Тевари
источник
3
Я прочитал 5 похожих вопросов с множеством ответов, и это лучший. Спасибо!
Дорогая,
1
Вы также можете добавить свойства в категорию. См. Ответ @Pebby.
атулхатри
7

Расширение : сделать методы частными и добавить свойства нашего собственного настраиваемого класса, а не класса Apple.

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

Анкит Гарг
источник
Просто и элегантно. Так держать
Абдул Ясин
3

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

@interface SomeClass (Private)

@property (nonatomic, assign) id newProperty;

@end

NSString * const kNewPropertyKey = @"kNewPropertyKey";

@implementation SomeClass (Private)

@dynamic newProperty;

- (void)setNewProperty:(id)aObject
{
    objc_setAssociatedObject(self, kNewPropertyKey, aObject, OBJC_ASSOCIATION_ASSIGN);
}

- (id)newProperty
{
    return objc_getAssociatedObject(self, kNewPropertyKey);
}

@end

Обратитесь: http://inchoo.net/dev-talk/ios-development/how-to-add-a-property-via-class-category/

PradeepKN
источник
2
@interface SomeClass ()


- (void) anAdditionalMethod;


@end

Я думаю, что это не способ объявлять категорию. Категория должна иметь название

@interface SomeClass (XYZ)


- (void) anAdditionalMethod;


@end

например

@interface NSMutableArray (NSMutableArrayCreation)

+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;

@end

Заявлено Apple для NSMutableArray

Изучение
источник
Вот как вы объявляете и расширяете, а не категорию -> @interface SomeClass ()
ChavirA
0

Расширение ios похоже на C #, абстрактный класс java или интерфейс
категории ios аналогично C #, расширение класса java

Добавить080bbA
источник
4
Ваш ответ такой же, как «кошка похожа на тигра, отвечая слепому». Lol
Муруганандхам К
1
на самом деле это не так. Это наиболее прямое и быстрое объяснение, если вы знаете C # или java.
Add080bbA
Совсем не очень информативный и почти не ответил на вопрос.
KVISH
0

Категории

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

Расширения

Расширения позволяют вам переопределить свойство или добавить новое свойство к существующему родительскому классу. Синтаксически то же самое для категорий, у которых нет имени, и представлены как @interface class () .m файл отсутствует, и метод, объявленный в расширении, необходимо реализовать в @ реализации родительского файла

Дополнительная помощь по этой ссылке

Сурьянараян Саху
источник
0

Вот мое понимание:

Расширения обычно используются для добавления дополнительных функций в наш собственный « пользовательский класс ». Мы можем добавить частные методы или свойства, расширяющие интерфейс класса, которые можно использовать в реализации класса.

Расширения должны быть записаны в том же файле, что и класс. Следовательно, вы не можете писать расширения для предопределенных типов, таких как String, Float и т. Д.

С другой стороны, категории можно использовать для добавления дополнительных методов к уже существующим классам. Пример: мы можем создавать наши собственные методы, расширяя класс String. Обратите внимание, что мы не можем создавать дополнительные свойства в категориях. Также основным преимуществом категорий является то, что мы можем записывать категории в любом другом файле, за пределами файла, из которого выходит ваш класс.

Также при создании категорий вы должны дать ей имя в скобках. Но для расширения имя не требуется. Поэтому иногда их также называют анонимными категориями.

iPhoneDeveloper
источник
Вы немного сбились с пути.
Абдул Ясин
@iPhoneDeveloper Мы можем написать расширение для предопределенных типов. Пожалуйста, проверьте эту ссылку - stackoverflow.com/a/33942484/2060508
yo2bh