実行時の魔法: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ランタイムプログラミングガイド

Source: https://habr.com/ru/post/J120662/


All Articles