14

C ++のdynamic_castに相当するObjective-Cはありますか?

これを使用して偽造することができます:

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

しかし、頻繁に入力する必要がない場合でも、これは入力するコードがたくさんあります。

私は少し錆びているので、これは正しくないかもしれませんが、C++での同等のものは次のようになると思います。

MyClass safeObject = dynamic_cast<MyClass>(orginalObject);

ここでのコンテキストは、パラメーターがより一般的なクラスのタイプとして定義されているブロックですが、このブロックでは、それが特定のサブクラスであることを「知っています」。(MyClass *)originalObjectそれにもかかわらず、私はそれを盲目的にキャストして、理論的に起こりうるエラーを無視したくありません。

明確にするために、私はが大好きですが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オブジェクトを除いてまったく同じように動作する必要があります。


バニラ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 に答える