Objective-C dynamic_cast?

Ste*_*her 12 objective-c

是否存在与C++的dynamic_cast相当的Objective-C?

它可以用这个伪造:

MyClass *safeObject = [object isKindOfClass: [MyClass class]]
                      ? (MyClass *)originalObject : nil;
Run Code Online (Sandbox Code Playgroud)

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

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

MyClass safeObject = dynamic_cast<MyClass>(orginalObject);
Run Code Online (Sandbox Code Playgroud)

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

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

Lil*_*ard 17

如果您愿意使用Objective-C++,您可以非常轻松地编写它:

template<typename T> inline T* objc_cast(id from) {
    if ([from isKindOfClass:[T class]]) {
        return static_cast<T*>(from);
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

这应该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
Run Code Online (Sandbox Code Playgroud)

这个版本不是很好用,因为你不得不说

UIButton *button = [UIButton cast:someView];
Run Code Online (Sandbox Code Playgroud)

在两个版本中,结果值都是nil如果转换失败.


小智 7

试试这个宏:

#define objc_dynamic_cast(obj, cls) \
    ([obj isKindOfClass:(Class)objc_getClass(#cls)] ? (cls *)obj : NULL)
Run Code Online (Sandbox Code Playgroud)

而且也不要忘记

#include <objc/runtime.h>
Run Code Online (Sandbox Code Playgroud)

使用它像:

MyClass *safeObject = objc_dynamic_cast(originalObject, MyClass);
Run Code Online (Sandbox Code Playgroud)