Objective-C dynamic_cast?
Существует ли Objective-C эквивалент С++ dynamic_cast?
Его можно подделать, используя это:
MyClass *safeObject = [object isKindOfClass: [MyClass class]]
? (MyClass *)originalObject : nil;
Но это много кода для ввода, даже если мне не нужно вводить его часто.
Я немного ржавый, так что это может быть не совсем правильно, но я считаю, что эквивалент в С++ будет:
MyClass safeObject = dynamic_cast<MyClass>(orginalObject);
Контекст здесь - это блок, где параметр определяется как тип более общего класса, но в этом блоке я "знаю" его конкретный подкласс. Тем не менее, я не хочу просто бросать его вслепую с помощью (MyClass *)originalObject
и игнорировать теоретически возможную ошибку.
Чтобы быть ясным, хотя мне бы понравился dynamic_cast
, я был бы доволен альтернативным подходом к безопасному обращению с этим делом.
Ответы
Ответ 1
Если вы хотите использовать Objective-C ++, вы можете легко это записать:
template<typename T> inline T* objc_cast(id from) {
if ([from isKindOfClass:[T class]]) {
return static_cast<T*>(from);
}
return nil;
}
Это должно вести себя точно как dynamic_cast<>
за исключением объектов obj-c.
Если вы хотите придерживаться ванильного Obj-C, вы можете получить аналогичное поведение с методом класса на NSObject
:
@interface NSObject (Cast)
+ (instancetype)cast:(id)from;
@end
@implementation NSObject (Cast)
+ (instancetype)cast:(id)from {
if ([from isKindOfClass:self]) {
return from;
}
return nil;
}
@end
Эта версия просто не так хороша в использовании, так как вы должны сказать что-то вроде
UIButton *button = [UIButton cast:someView];
В обеих версиях результирующее значение nil
, если сбой выполняется.
Ответ 2
Попробуйте этот макрос:
#define objc_dynamic_cast(obj, cls) \
([obj isKindOfClass:(Class)objc_getClass(#cls)] ? (cls *)obj : NULL)
А также не забывайте
#include <objc/runtime.h>
Используйте его как:
MyClass *safeObject = objc_dynamic_cast(originalObject, MyClass);
Ответ 3
- Я не думаю, что есть.
- Я думаю, что место для ошибки здесь довольно мало.
- Но если вы настаиваете, макрос будет работать нормально?