実行時の魔法:Objective-Cオブジェクトの検査

Objective-Cは、他の言語とは異なり、オブジェクトのポインタータイプは、メッセージを送信するときの実行時にはあまり重要ではなく、コンパイル時にのみ使用されます。 実行して確認するだけです:

NSNumber *string = [[NSString alloc] initWithString: @"hello"]; NSLog(@"%@", string);
      
      







疑いの余地はありませんでした;-)私たちは一般的にどんなタイプやIDでも使用できます。

実行時に、すべての必要な情報はisa変数を介してクラスオブジェクトから取得されます。 タイプClass (または単なるクラス)のクラスオブジェクトはシングルトンであるため、オブジェクトのクラスはポインターの単純な比較によって比較できます。

 [object class] == [object2 class];
      
      







クラスオブジェクトからすべての情報を収集すると、実行時にオブジェクトのインターフェイスを簡単に復元できます。





オブジェクト



 // : - (Class) class; + (Class) class; // : - (Class) superclass; + (Class) superclass; //  : Protocol ** class_copyProtocolList(Class cls, unsigned int *outCount); //  : Ivar * class_copyIvarList(Class cls, unsigned int *outCount); //  : Method * class_copyMethodList(Class cls, unsigned int *outCount); //  : objc_property_t * class_copyPropertyList(Class cls, unsigned int *outCount);
      
      







変数



 // : const char * ivar_getName(Ivar ivar); // : const char * ivar_getTypeEncoding(Ivar ivar);
      
      







方法



 // : SEL method_getName(Method method); //       sel_getName(method_getName(method)); //  : unsigned method_getNumberOfArguments(Method method); //     index: char * method_copyArgumentType(Method method, unsigned int index); void method_getArgumentType(Method method, unsigned int index, char *dst, size_t dst_len); // : char * method_copyReturnType(Method method); void method_getReturnType(Method method, char *dst, size_t dst_len);
      
      







プロパティ



名前、タイプ、属性:

const char * property_getAttributes(objc_property_tプロパティ) ;



オブジェクトの行



ClassProtocolSELは、名前のある行を要求できます。

 NSString * NSStringFromClass (Class aClass); SString * NSStringFromProtocol (Protocol *proto); NSString *NSStringFromSelector (SEL aSelector);
      
      







悲しいかな、Ivar、Method、objc_property_tには独自の関数がないため、それらを記述する必要がありました。

 NSString *OIStringFromIvar (Ivar ivar); NSString *OIStringFromMethod (Method method); NSString *OIStringFromProperty (objc_property_t property);
      
      







残念ながら、すべての情報が利用できるわけではありません。 コンパイルすると、次のものが失われます。

メソッド宣言内の#definetypedef 、オブジェクトタイプ、およびパラメーター名。



スタイルオブジェクトタイプ:@「NSObject」は、objcランタイムのドキュメント化されていないプロパティです。



インターフェイスを宣言した場合:

 @interface MyObject : NSObject { NSNumber *number; } - (void) setNumber: (NSNumber *) number; - (NSNumber *) number; @end
      
      







、次に機能します:

 OIStringFromIvar (ivar); // - (void) setNumber: (NSNumber *) number; OIStringFromMethod (method); // - (NSNumber *) number; OIStringFromMethod (method);
      
      







それに応じて戻ります:

 NSNumber *number - (void) setNumber: (id) arg1 - (id) arg1
      
      







参照資料



オブジェクトインスペクター

Objective-Cランタイムリファレンス

Objective-Cランタイムプログラミングガイド



All Articles