Вы должны попробовать что-то вроде:
#if TARGET_OS_IPHONE
typedef UIImage NUIImage; // NUIImage is an alias for UIImage
#else
typedef NSImage NUIImage; // NUIImage is an alias for NSImage
#endif
И затем использовать NUIImage везде, где бы вы использовали NSImage или UIImage.Typedef наследуется от C, поэтому это только стоимость компиляции без влияния на время выполнения (например, NSClassFromString(@"NUIImage")
вернет nil
при прочих равных условиях).Это заставляет компилятор считать одну вещь псевдонимом другой.Если вы принимаете строгие соглашения C, вы, вероятно, назвали бы это NUIImage_t
.
Ниже приведена отредактированная версия моего первоначального ответа, основанная на оригинальном, ошибочном прочтении, которое связано с использованием вопроса.конкретный класс, который может существовать или не существовать, причем этот факт неизвестен до времени выполнения.Это точно для такой ситуации, но не особенно важно:
Вам не нужно находить решение, которое работает в определениях методов или в любых других определениях, обычно используемых в заголовочном файле;Вы можете просто использовать имя класса там.В Objective-C вы всегда ссылаетесь на объекты по указателю, и все указатели выглядят одинаково для аппаратного обеспечения.Таким образом, использование типизированных указателей в исходном коде является фикцией для программиста (в том числе косвенно через соответствующие предупреждения компилятора), не влияя на сгенерированный двоичный файл.
Пока определение, например,после компиляции не имеет значения, доступны ли ни SomeClass
, ни SomeOtherClass
во время выполнения:
- (SomeClass *)someMethod:(SomeOtherClass *)argument;
Вы не получите исключение только за то, что объявили метод.
Единственное место, которое вам действительно нужно использовать NSClassFromString
, это где вы делаете начальную ветвь относительно того, определен ли тип объекта или нет.Например, вы можете написать следующий класс:
@interface SomeClassThatUsesSomeOtherClass
- (id)init;
@property (nonatomic, readonly) SomeOtherClass *otherClassInstance;
- (void)doSomeTask;
- (SomeOtherClassResult *)doSomeOtherTask;
@end
/* elsewhere */
@implementation SomeClassThatUsesSomeOtherClass
@synthesize otherClassInstance;
- (id)init
{
// blah blah blah, standard init stuff here
// switch is made implicitly here, because if we get nil back
// then we'll end up with nil in 'otherClassInstance' — we're
// considering the class not existing to be equivalent to any
// other issue that might cause an instance not to be created
otherClassInstance = [[NSStringFromClass(@"SomeClass") alloc] init];
if(!otherClassInstance)
{
[self release];
return nil;
}
// blah blah blah, rest of standard init
}
// you'll need a suitable dealloc, too
- (void)doSomeTask
{
[self.otherClassInstance doAThing];
[self.otherClassInstance doAnotherThing];
}
- (SomeOtherClassResult *)doSomeOtherTask
{
return [self.otherClassInstance doAThirdThing];
}
@end
И ваш код полностью безопасен, автоматически работает или не работает в зависимости от того, доступен ли класс.