Objective-Cでポインタタイプを判断
2232 ワード
今日、Objective-C++でクラスのポインタメンバー変数がObjective-CオブジェクトまたはC++オブジェクトに属するとどのように判断するかという質問をされましたが、この質問を聞いた後、Objective-CのRuntimeには判断できる関数があるはずですが、後で私の考えが間違っていることに気づきました.Objective-CオブジェクトとC++オブジェクトはメモリ構造上全く異なるため、ポインタの[obj class]メソッドを呼び出すとObjective-Cクラスは正常に動作しますが、C++クラスは直接crashします.このメソッドはC++クラスを呼び出すのは野ポインタにアクセスするのと同じなので、Objective-CオブジェクトのメソッドでもC++オブジェクトのメソッドでも呼び出すことはできません.このポインタのタイプを判断するには、コンパイル時にしか実現できず、実行時にそのタイプを判断できない.野ポインタを判断できないように、WrapperとBridgeを符号化時に作成することで、Objective-C++の設計原則に従うしかない.
コンパイル時にtypeofでポインタのタイプを取得し、typeidを使用してタイプの名前を取得します.typeidはC++RTTI(Run-Time Type Information、ランタイムタイプ情報)でポインタのタイプ情報を取得する演算子で、Objective-C++でもObjective-Cに適したクラスです.
import “VSAppDelegate.h”
include
class CTest { public:
};
@implementation VSAppDelegate(BOOL)アプリケーション:(UIApplication)app didFinishLaunchingWithOptiions:(NSDictionary)launchOptiions{CTest a=(CTest)123;//aを野ポインタNSLog(@"%@",[NSString stringWithUTF 8 String:typeid(typeof(a)).name()));NSLog(@"%@",[NSString stringWithUTF 8 String:typeid(typeid(typeid(typeof(a))).NSLog(@",[NSString stringWithUTF 8 String:typeid(typeid(typeid(typeid(typeid)of(app).name());return YES;}
@end以上のコードの出力結果は:
P 5 CTest P 13 UIApplicationではpはpointer,5はCTestの長さ以上の結果がCLang+LLVMコンパイラの結果であり,コンパイラtypeidのname出力の文字列が異なるためである.
また、Objective-Cの@encodeキーワードでポインタのタイプを取得し、@を返すとObjective-Cであるクラスを表し、^{...}を返すとC++であるクラスを表す方法も紹介されています.添付コードは以下の通りです.
import “VSAppDelegate.h”
include
class CTest { public:
};
@implementation VSAppDelegate(BOOL)アプリケーション:(UIApplication)app didFinishLaunchingWithOptiions:(NSDictionary)launchOptiions{CTest a=(CTest)123;//aを野ポインタNSLog(@"%@",[NSString stringWithUTF 8 String:@encode(@encode(typeof(a)))]));NSLog(@"%@",[NSString stringWithUTF 8 String:@encode(@encode(typeof(app))))))))))))));NSLog(@",[ NSString string stringWithUTF 8 String:@encode(@encode(ty)]); return YES;}
@end以上のコードの出力結果は:
^{CTest=i}@はいずれもtypeofコンパイル時にタイプ情報を取得する方式であり,typeidはC++提供,@encodeはObjective-C提供であり,いずれも実行時にタイプ情報を取得する方式であり,具体的な優劣は検討される.
こんなに長く書いても疲れたので、ついでに最近読んでいる小説をお勧めします.http://www.xin17k.com/books/4088.html
コンパイル時にtypeofでポインタのタイプを取得し、typeidを使用してタイプの名前を取得します.typeidはC++RTTI(Run-Time Type Information、ランタイムタイプ情報)でポインタのタイプ情報を取得する演算子で、Objective-C++でもObjective-Cに適したクラスです.
import “VSAppDelegate.h”
include
class CTest { public:
int a;
};
@implementation VSAppDelegate
@end以上のコードの出力結果は:
P 5 CTest P 13 UIApplicationではpはpointer,5はCTestの長さ以上の結果がCLang+LLVMコンパイラの結果であり,コンパイラtypeidのname出力の文字列が異なるためである.
また、Objective-Cの@encodeキーワードでポインタのタイプを取得し、@を返すとObjective-Cであるクラスを表し、^{...}を返すとC++であるクラスを表す方法も紹介されています.添付コードは以下の通りです.
import “VSAppDelegate.h”
include
class CTest { public:
int a;
};
@implementation VSAppDelegate
@end以上のコードの出力結果は:
^{CTest=i}@はいずれもtypeofコンパイル時にタイプ情報を取得する方式であり,typeidはC++提供,@encodeはObjective-C提供であり,いずれも実行時にタイプ情報を取得する方式であり,具体的な優劣は検討される.
こんなに長く書いても疲れたので、ついでに最近読んでいる小説をお勧めします.http://www.xin17k.com/books/4088.html