14

是否有与 C++ 的 dynamic_cast 等效的 Objective-C?

可以使用以下方法伪造:

MyClass *safeObject = [object isKindOfClass: [MyClass class]]
                      ? (MyClass *)originalObject : nil;

但这需要输入很多代码,即使我不需要经常输入。

我有点生疏,所以这可能不太正确,但我相信 C++ 中的等价物是:

MyClass safeObject = dynamic_cast<MyClass>(orginalObject);

这里的上下文是一个块,其中参数被定义为更通用类的类型,但在这个块中,我“知道”它是一个特定的子类。尽管如此,我不想只是盲目地使用它(MyClass *)originalObject并忽略理论上可能的错误。

需要明确的是,虽然我很喜欢 a dynamic_cast,但我也很乐意使用另一种方法来安全地处理这种情况。

4

3 回答 3

17

如果你愿意使用 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 对象外,它的行为应该完全一样。


如果您想坚持使用 vanilla 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如果转换失败。

于 2012-08-29T05:03:22.010 回答
8

试试这个宏:

#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);
于 2012-05-11T20:00:05.440 回答
3
  1. 我不认为有。
  2. 我认为这里的错误空间很小。
  3. 但如果你坚持,宏就行了?
于 2012-05-11T19:57:51.657 回答