iOS runtime(理論編)

1868 ワード

一.objc_からmsgSendは

[receiver message] 
// 
objc_msgSend(receiver, selector) 

メソッドを呼び出すと、次のように実行されます.rutimeシステムはメソッド呼び出しをメッセージ送信に変換し,メソッドの呼び出し者とメソッドセレクタをパラメータとして渡す.2.メソッドの呼び出し元はisaポインタで属するクラスを見つけ、cacheまたはmethodListsでメソッドを検索し、見つけたら対応するメソッドにジャンプして実行します.3.クラスにメソッドが見つからない場合はsuper_classは上位レベルのスーパークラスに検索されます.NSObjectがずっと見つかってもこの方法が見つからない場合は、メッセージ転送がトリガーされる可能性があります.

二.runtimeの用語のデータ構造


上で述べたのは、実行過程にいくつかの用語があります.次に、大まかに紹介します.
1.SEL
selectorはメソッドセレクタで、実は名前と同じように、日常生活の中で、私たちは人名を通じて誰が誰なのかを識別します.Objective-Cはコンパイルの際、メソッドの名前に基づいて、このメソッドを区別するための唯一のIDを生成します.このIDはSELタイプです.メソッドの名前が同じであれば、IDは同じであることに注意してください.つまり、スーパークラスでもサブクラスでも、スーパークラスとサブクラスの関係があるかどうかにかかわらず、名前が同じであればIDは同じです.
    -(void)setWidth:(int)width;   
    -(void)setWidth:(double)width;   

このような関数はコンパイルエラーとみなされ、最終的には非常に奇妙なObjective-Cの特色のある関数の名前が付けられました.
    -(void)setWidthIntValue:(int)width;   
    -(void)setWidthDoubleValue:(double)width;   

本質的には、SELはメソッドを指すポインタにすぎず、メソッドのクエリー速度を速めるために存在します.
2.Class
Classはobjc_を指していますclass構造体のポインタ
3.Method
Methodはクラス内のメソッドのタイプを表します
4.Ivar
Ivarはメンバー変数を表すタイプです.
5.IMP
コンパイラによって生成される関数ポインタです.ObjCメッセージを開始すると、最終的に実行されるコードは、この関数ポインタによって指定されます.IMPという関数ポインタはこの方法の実現を指している.あるインスタンスのメソッドを実行するエントリが得られた場合、メッセージ伝達フェーズを迂回してメソッドを直接実行することができ、これは後述するCacheで説明される.IMPが指す方法とobjc_msgSend関数のタイプは同じで、パラメータにはidとSELタイプが含まれています.各メソッド名はSELタイプのメソッドセレクタに対応し、各インスタンスオブジェクトのSELに対応するメソッド実装は必ず一意であり、idとSELパラメータのセットによって一意のメソッド実装アドレスを決定することができる.一方、決定された方法は、idおよびSELパラメータの一意のセットのみである.
6.Cache
Cacheはメソッド呼び出しのパフォーマンスを最適化し、インスタンスオブジェクトがメッセージを受信するたびにisaポインタが指すクラスのメソッドリストに応答可能なメソッドを直接検索しません.毎回検索効率が低すぎるため、Cacheで優先的に検索します.Runtimeシステムは呼び出されたメソッドをCacheに格納し,1つのメソッドが呼び出されると今後も呼び出される可能性があり,次回検索時にはより効率的になる.コンピュータの構成原理でCPUがホストメモリを迂回してCacheにアクセスするように.