Do Objective-C Названия категорий ничего не делают?
Класс может быть расширен в Objective C с использованием такой категории, как:
@interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
@end
/////////////////////////////
@implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
@end
В этом маленьком примере я бы добавил метод myFabulousAddition
в NSString. Тогда я мог бы называть его [anNSString myFabulousAddition]
так же, как если бы он был частью набора методов NSString. Отличный и полезный.
В документах Apple, касающихся категорий, состояние документов:
Нет ограничений на количество категорий, которые вы можете добавить к класса, но каждое имя категории должно быть разные, и каждый должен объявить и определите другой набор методов.
Что делать, если у вас есть что-то вроде этого:
@interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
@end
@interface NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition; // a DIFFERENT fabulous additional method
// BUT with same name as the other category
@end
/////////////////////////////
@implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
@end
@implementation NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition {
// do something equally fabulous, but DIFFERENT...
}
@end
Отсутствие имени в скобках указывает, что форма является расширением для класса, например:
@interface MyObject () // No name -- an extension vs category to MyObject
- (void)setNumber:(NSNumber *)newNumber;
@end
Имеет ли название категории какое-либо значение для компилятора или компоновщика? Является ли имя категории частью подписи метода в любом случае или является частью примитивного пространства имен? Если название категории бессмысленно, как вы узнаете, собираетесь ли вы топать по другому методу и получить поведение undefined?
Ответы
Ответ 1
Способ избежать топания методов - это префикс имен ваших категорий, например:
@interface NSString (MyCompanyCategoryName)
- (NSString *)MYCO_fabulousAddition;
@end
Если вы получаете столкновение имен методов из разных категорий, то какая "победа" во время выполнения полностью undefined.
Название категории почти совершенно бесполезно, за исключением того, что безымянная категория (т.е. ()
) зарезервирована для расширений класса. Методы из расширений класса должны быть реализованы в классе @implementation
.
Ответ 2
Название категории не означает ничего особенного, это просто идентификатор. Если компоновщик (или загрузчик времени выполнения) решает дать вам предупреждение, нет способа сказать, что несколько категорий определяют один и тот же метод.
Ответ 3
Поведение (в значительной степени) непредсказуемо - одна из категорий победит, но вы не можете сказать, какой из них. Кроме того, я думаю, что вполне возможно, что вы начнете с одной реализации и закончите с другой (если вторая категория загружается после первого).
Ответ 4
Он, безусловно, действует как идентификатор, с точки зрения программиста. В методе класса компилятора методы класса просто добавляются как расширение класса (из которого оно распространяется), независимо от имени.
И да, вы можете добавить категории одного и того же класса с одинаковыми идентификаторами, даже с одинаковыми функциями. Но вы определенно не можете переопределить какую-либо функцию, потому что категории являются частью класса после их определения (так же, как вы не можете переопределить функцию класса из этого класса).
Поскольку они добавляются во время выполнения, они не создают никакой ошибки, и только во время выполнения компилятор выбирает эту функцию, что совершенно непредсказуемо.
Ответ 5
Я считаю, что они не имеют никакого значения. Вы действительно не используете их в своем коде... Поскольку они являются категориями и... семантикой категории... просто категоризировать что-то, я думаю, что это несколько логично...
Я бы сказал, что они просто собирают методы...
С другой стороны, ваш вопрос очень важен... ВЫ НЕ ЗНАЕТЕ, если вы переопределяете метод. Если вы находитесь в одном проекте, тогда компилятор выдает предупреждение (или ошибку? Я не помню), однако, если вы переопределяете метод из библиотеки, то.. вам не повезло...