Runtimeランタイム1:クラス
5242 ワード
概要
この特性は、
objc_object isaポインタが属するクラスを指すことから、この構造体には1つのフォント、すなわちインスタンスが属するクラスを指すisaポインタしかないことがわかる.
Class isaポインタはMeta Class(メタクラス)を指し、クラスもオブジェクトである以上、 を引き出した.
Meta Class isaポインタはベースクラスMeta Classを指します.
動的生成
クラスの作成
パラメータ1:親パラメータ2:名前パラメータ3:開バイト長
メンバー変数の作成
パラメータ1:クラス名パラメータ2:名前パラメータ3:バイト長パラメータ4:メモリ整列パラメータ5:パラメータタイプ"@"公式解釈An object(whether statically typed or typed id)(オブジェクト静的タイプまたはidタイプ)具体的なタイプ参照可能官方ドキュメント
属性の作成
属性カテゴリの説明
作成方法
パラメータ1、クラス名パラメータ2、SELに追加されたメソッド名パラメータ3、IMPポインタ(IMPはImplementationの略であり、一つのメソッド実装を指すポインタであり、それぞれのメソッドに対応するIMPがある)パラメータ4、ここでtypesパラメータは「i@:@」であり、具体的なタイプは公式文書iの戻り値タイプintを参照し、vであればvoid@パラメータid(self):SEL(_cmd)@id(str)V@:戻り値がvoidにSELパラメータ(An object(wheter statically typed or typed)があることを示す.
ここでは関数と方法を実現する必要があります
オブジェクトの作成
オブジェクトを作成するにはシステムに登録する必要があります
メンバー変数の作成方法と同じですが、パラメータのタイプが異なります.
メンバー変数の割当て#メンバーヘンスウノワリアテ#
属性の取得
Objective-C
言語は動的言語であり、多くの静的言語がコンパイルとリンクの時期にしたことを実行時に処理します.この特性は、
Objective-C
がコンパイラだけでなく、コンパイルされたコードを実行するためにランタイムシステムも必要であることを意味する.Objective-C
では、このランタイムシステムはオペレーティングシステムのように動作します.これにより、すべての動作が正常に動作します.このランタイムシステムはObjc Runtime
です.Objc Runtime
は実はRuntime
ライブラリで、基本的にはCとアセンブリで書かれており、このライブラリはC言語にオブジェクト向けの能力を持たせた.objc_object
objc_object
はクラスの一例を示す構造体であるstruct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
Objective-C
オブジェクトにメッセージを送信すると、実行時ライブラリはインスタンスオブジェクトのisaポインタに基づいてこのインスタンスオブジェクトが属するクラスを見つけます.Runtime
ライブラリは、クラスのメソッドリストおよび親クラスのメソッドリストで、メッセージに対応するselector
が指すメソッドを探します.見つけたらこの方法を実行します.Class
Objective-C
クラスは、Class
タイプによって表され、実際にはobjc_class
構造体を指すポインタであり、つまりClass
自体もオブジェクトであることを意味する.定義は次のとおりです.typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; //
const char *name OBJC2_UNAVAILABLE; //
long version OBJC2_UNAVAILABLE; // , 0
long info OBJC2_UNAVAILABLE; // ,
long instance_size OBJC2_UNAVAILABLE; //
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; //
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; //
struct objc_cache *cache OBJC2_UNAVAILABLE; //
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; //
#endif
} OBJC2_UNAVAILABLE;
objc_object
ポインタであり、クラスを指すisa
ポインタを含む.では、これらには問題があります.このisa
ポインタは何を指していますか.クラスメソッドを呼び出すために、このクラスのisaポインタは、これらのクラスメソッドを含むobjc_class
構造体を指さなければならない.これはMeta Class
の概念Meta Class
Meta Class
は、クラスのすべてのクラスメソッドを格納するクラスオブジェクトのクラスです.Meta Class
もクラスである以上、メッセージを送信することもできます.では、isa
は何を指していますか.このような構造が無限に延びないように、Objective-C
の設計者は、すべてのMeta Class
のisa
をベースクラスのMeta Class
に指向させ、それらの所属クラスとする.すなわち、任意のNSObject
継承システムの下のMeta Class
は、NSObject
のMeta Class
を自分の属するクラスとして使用し、ベースクラスのMeta Class
のisa
ポインタはそれ自身を指す.これで完璧な閉ループが形成された.動的生成
Objective-C
が動的言語である以上、すべては実行時に動的に作成できます.クラスの作成
パラメータ1:親パラメータ2:名前パラメータ3:開バイト長
Class Student = objc_allocateClassPair([Person class], "Student", 0);
メンバー変数の作成
パラメータ1:クラス名パラメータ2:名前パラメータ3:バイト長パラメータ4:メモリ整列パラメータ5:パラメータタイプ"@"公式解釈An object(whether statically typed or typed id)(オブジェクト静的タイプまたはidタイプ)具体的なタイプ参照可能官方ドキュメント
class_addIvar(Student, "_studentID", sizeof(NSString *), log2(sizeof(NSString *)), "^NSString");
class_addIvar(Student, "_classNumber", sizeof(NSInteger), log(sizeof(NSInteger)), "i");
属性の作成
属性カテゴリの説明
objc_property_attribute_t type = {"T", "@\"NSString\""}; //
objc_property_attribute_t iver = {"V", "_studentID"}; //
objc_property_attribute_t ownership = {"C", ""}; //
objc_property_attribute_t nonatomic = {"N", ""};//
objc_property_attribute_t attributes[] = {type, iver, ownership, nonatomic};
// ,@1 , @2: , @3:
class_addProperty(Student, "sid", attributes, 4);
作成方法
パラメータ1、クラス名パラメータ2、SELに追加されたメソッド名パラメータ3、IMPポインタ(IMPはImplementationの略であり、一つのメソッド実装を指すポインタであり、それぞれのメソッドに対応するIMPがある)パラメータ4、ここでtypesパラメータは「i@:@」であり、具体的なタイプは公式文書iの戻り値タイプintを参照し、vであればvoid@パラメータid(self):SEL(_cmd)@id(str)V@:戻り値がvoidにSELパラメータ(An object(wheter statically typed or typed)があることを示す.
class_addMethod(Student, @selector(test:), (IMP)test, "v@:^NSString");
ここでは関数と方法を実現する必要があります
void test(id self, SEL _cmd, NSString *str) {
//
}
- (void)test:(NSString *)str {
NSLog(@"%@", str);
}
オブジェクトの作成
オブジェクトを作成するにはシステムに登録する必要があります
objc_registerClassPair(Student);
メンバー変数の作成方法と同じですが、パラメータのタイプが異なります.
BOOL isSuccess = class_addIvar(Student, "studentOne", sizeof(NSString *), 0, "@");
メンバー変数の割当て#メンバーヘンスウノワリアテ#
//
Ivar ivar = class_getInstanceVariable(Student, "_studentID");
//
object_setIvar(studentOne, ivar, @"4321");
//
id value = object_getIvar(studentOne, ivar);
属性の取得
//
objc_property_t property = class_getProperty(Student, "sid");
//
const char *pName = property_getName(property);
//
const char *pAtrributes = property_getAttributes(property);