Использование категории в Objective-C

Я вижу унаследованный код, который выглядит следующим образом:

@interface SomeClass (private)

Это находится в SomeClass.m, файле реализации. Существует сопровождающий файл заголовка, который не предполагает, что класс использует категорию. Является ли (private) в этом случае только плохим именем, присвоенным категории для SomeClass? И я предполагаю, что совершенно правильно указывать такие категории в реализации?

Ответ 1

Это не имя "private", которое делает его закрытым; методы являются частными, потому что они находятся в категории, объявленной в файле реализации.

Существует три применения категории, каждая из которых добавляет методы в класс (обратите внимание: только методы, а не iVars)

Расширение существующего класса Cocoa

Это позволяет добавлять собственные методы в существующий класс. Например, если вы хотите расширить NSString для применения специальной капитализации, вы можете создать новый класс, называемый NSString + Capitals. в NSString + Capitals.h у вас будет:

@interface NSString (Capitals)

-(NSString *)alternateCaps:(NSString *)aString;

@end

и в NSString + Capitals.m вы должны реализовать метод

@implementation NSString (Capitals)
-(NSString *)alternateCaps:(NSString *)aString
{
    // Implementation
}

Частные методы для класса

Это то же самое, что и выше, за исключением того, что дополнительные методы объявлены и определены в файле реализации (.m) Обычно способ иметь частные методы - потому что они не находятся в файле .h(который является номером # импортированные другими классами), они просто не видны. В этом случае реализация методов выполняется в собственном блоке реализации. например

// someClass.m
@interface someClass (extension)
-(void)extend;
@end

@implementation someClass
    // all the methods declared in the .h file and any superclass
    // overrides in this block
@end

@implementation someClass (extension)
-(void)extend {
    // implement private method here;
}

Расширение класса (Новое для 10.5 Leopard)

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

// someClass.m
@interface someClass ()
-(void)extend;
@end

@implementation someClass
    // all the methods declared in the .h file and any superclass
    // overrides in this block
    // Implement private methods in this block as well.
-(void)extend {
    // implement private method here;
}

@end

Здесь ссылка в документы Apple по категориям и расширениям.

Ответ 2

"Private" - это просто имя, которое предполагает, что методы не являются общедоступными и используются для внутренней реализации класса, но в объявлении категории это не действует.

Кроме того, методы, определенные в категории, добавляются к определению класса во время выполнения, поэтому в сопроводительном файле заголовка не требуется объявлять, что он использует категорию - он автоматически "используется".

Ответ 3

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