Существует ли способ обеспечить реализацию метода (который носит то же самое имя метода, определенного платформой), только, когда метод уже не определяется в системе? Например, метод [NSSomeClass someMethod:]
существует только в Mac OS X 10.6 и если мое выполнение приложения в 10,5, я обеспечу что определение метода в категории. Но когда выполнение приложения в 10,6, я хочу, чтобы обеспеченный ОС метод работал.
Фон: я создаю приложение, предназначенное и для 10,5 и для 10.6. Проблема состоит в том, что я недавно понял тот метод +[NSSortDescriptor sortDescriptorWithKey:ascending:]
только существует в 10,6, и мой код уже замусорен тем вызовом метода. Я мог обеспечить реализацию по умолчанию для него (так как это время, не слишком трудно реализовать его сам), но я хочу, чтобы "собственное" было названо каждый раз, когда мое выполнение приложения на 10,6. Кроме того, если я встречаюсь с подобными проблемами в будущем (с большим количеством difficult-to-implement-myself методов), я не смог сходить с рук обеспечение замены остроты.
Этот вопрос, неопределенно подобный, чтобы Переопределить метод через Категорию ObjC и назвать реализацию по умолчанию? но различие - то, что я хочу обеспечить реализации только, когда система уже не имеет того.
Спасибо.
Да, это возможно. Поскольку вы нацелены на 10.5+, я предполагаю, что вы используете среду выполнения ObjC2, что делает ее довольно простой.
В Справочнике по времени выполнения Objective-C есть все методы, которые вам понадобятся. В частности, вы можете использовать class_getClassMethod или class_getInstanceMethod, чтобы узнать, существует ли метод уже, а затем class_addMethod, чтобы привязать вашу реализацию к этому селектору, если у класса его еще нет.
В качестве альтернативы вы можете просто выполнить поиск и выполнить подпрограмму - [NSSortDescriptor initWithKey: ascending:]
, а затем добавить соответствующий оператор выпуска.
Это более громоздко в реализации, но гораздо менее уязвимо и подвержено ошибкам, чем изменение самого класса. Это особенно верно, если вы никогда не делали этого раньше. Вы, вероятно, потратите больше времени на то, чтобы разобраться с переопределением, чем просто на поиск.
Я бы скомпилировал + [NSSortDescriptor sortDescriptorWithKey: ascending:]
в категории в отдельный пакет. Затем в самом начале вашего основного файла проверьте, есть ли в классе NSSortDescriptor метод sortDescriptorWithKey: ascending:
с RespondsToSelector:
. Если это не реализовано (т.е. вы работаете на <10.6), загрузите пакет с помощью - [NSBundle loadAndReturnError:]
.
Таким образом, вы запустите предоставленный ОС метод на 10.6 и вашу реализацию на 10.5.
подумайте о компромиссе между изменением initWithKey: ascending: method и и добавлением нового метода во время выполнения - просто создайте подкласс NSSortDescriptor и замените все вызовы NSSortDescriptor на NSMySortDescriptor;
//NSMySortDescriptor.h
@interface NSMySortDescriptor : NSSortDescriptor {
}
- (id)initWithKey:(NSString *)keyPath ascending:(BOOL)ascending
@end
//NSMySortDescriptor.m
@implementation NSMySortDescriptor
- (id)initWithKey:(NSString *)keyPath ascending:(BOOL)ascending{
// check if super i.e. has initWithKey:ascending: method
if( [NSSortDescriptor instancesRespondToSelector:@selector(initWithKey:ascending:)] ) {
[NSSortDescriptor initWithKey:ascending:];
}
else{
// your custom realization for Mac OS X 10.5
//...
}
}
@end