久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

iOS 運(yùn)行時(shí)(Runtime)之 類和對(duì)象

 我愛你文摘 2019-09-22

Runtime簡介

Objective-C runtime 運(yùn)行 native code 。Java VM 運(yùn)行 byte code,。

原生碼(native code)又稱為機(jī)器碼(machine code),,是電腦的CPU可直接解讀的數(shù)據(jù),,是計(jì)算機(jī)可以直接執(zhí)行,執(zhí)行速度最快的代碼,。

字節(jié)碼(byte code)碼是一種中間狀態(tài)(中間碼)的二進(jìn)制代碼(文件),。需要轉(zhuǎn)譯后才能成為機(jī)器碼。

比如java:字節(jié)碼在運(yùn)行時(shí)通過JVM(JAVA虛擬機(jī))做一次轉(zhuǎn)換生成機(jī)器指令,,因此能夠更好的跨平臺(tái)運(yùn)行,。

Objc Runtime其實(shí)是一個(gè)Runtime庫,它基本上是用C和匯編寫的,,這個(gè)庫使得C語言有了面向?qū)ο蟮哪芰Α?/p>

在Runtime中,,對(duì)象可以用C語言中的結(jié)構(gòu)體表示,而方法可以用C函數(shù)來實(shí)現(xiàn),,另外再加上了一些額外的特性,。這些結(jié)構(gòu)體和函數(shù)被runtime函數(shù)封裝后,讓OC的面向?qū)ο缶幊套優(yōu)榭赡堋?/p>

當(dāng)程序執(zhí)行[object doSomething]時(shí),,會(huì)向消息接收者(object)發(fā)送一條消息(doSomething),,runtime會(huì)根據(jù)消息接收者是否能響應(yīng)該消息而做出不同的反應(yīng)。

動(dòng)態(tài)語言

靜態(tài)類型語言:指在編譯期間就去做數(shù)據(jù)類型檢查,,多數(shù)靜態(tài)類型語言要求在使用變量之前必須聲明數(shù)據(jù)類型,。比如C#,Java,。

動(dòng)態(tài)類型語言:指在運(yùn)行期間才去做數(shù)據(jù)類型檢查,,也就是說,用動(dòng)態(tài)語言編程時(shí),,永遠(yuǎn)不用去給任何變量去指定數(shù)據(jù)類型,。該語言會(huì)在你第一次給該變量賦值的時(shí)候,在內(nèi)部把數(shù)據(jù)類型記錄下來,。JavaScript、ruby或者Python是典型的動(dòng)態(tài)類型的語言,。

OC語言,,編譯階段并不能決定真正調(diào)用哪個(gè)函數(shù),只要函數(shù)聲明過即使沒有實(shí)現(xiàn)也不會(huì)報(bào)錯(cuò),。

我們常說OC是一門動(dòng)態(tài)語言,,就是因?yàn)樗偸前岩恍Q定性的工作從編譯階段推遲到運(yùn)行時(shí)階段。OC代碼的運(yùn)行不僅需要編譯器,,還需要運(yùn)行時(shí)系統(tǒng)(Runtime)來執(zhí)行編譯后的代碼,。

Runtime是一套底層純C語言API,OC代碼最終都會(huì)被編譯器轉(zhuǎn)化為運(yùn)行時(shí)代碼,通過消息機(jī)制決定函數(shù)調(diào)用方式,,這也是OC作為動(dòng)態(tài)語言使用的基礎(chǔ),。

isa

在Objective-C中,任何類的定義都是對(duì)象,。類和類的實(shí)例(對(duì)象)沒有任何本質(zhì)上的區(qū)別,。任何對(duì)象都有isa指針。

isa:是類指針,,之所以說isa是指針是因?yàn)镃lass其實(shí)是一個(gè)指向objc_class結(jié)構(gòu)體的指針,而isa 是它唯一的私有成員變量,即所有對(duì)象都有isa指針(isa位置在成員變量第一個(gè)位置)

objc_class是個(gè)結(jié)構(gòu)體,,而且第一個(gè)成員變量也是isa指針,這個(gè)指針指向的Class不是指向自己而是metaclass(元類)

metaclass

每個(gè)實(shí)例對(duì)象也就是struct objc_object結(jié)構(gòu)體它的isa的指針指向類對(duì)象Class,,而Class里也有個(gè)isa的指針, 指向metaClass(元類),。

元類是類對(duì)象的類,類對(duì)象是元類的實(shí)例,。

這時(shí)候相對(duì)于元類,,objc_class就是元類的實(shí)例對(duì)象。

基于這種設(shè)計(jì)模式,,不難發(fā)現(xiàn):

  1. 調(diào)用 '+' 開頭的類方法 是在調(diào)用元類的對(duì)象方法,,元類保存了類方法的列表和成員變量
  2. 由于每個(gè)類有且只有一個(gè),所以每個(gè)類對(duì)象都是其對(duì)應(yīng)元類的單例
  3. 元類(metaClass)也是類,,它也是對(duì)象,。
  4. 元類也有isa指針,它的isa指針最終指向的是一個(gè)根元類(root metaClass)
  5. 根元類的isa指針指向本身,這樣形成了一個(gè)封閉的內(nèi)循環(huán),。
iOS 運(yùn)行時(shí)(Runtime)之 類和對(duì)象

看圖說話:

1. objc_object中的isa指的是對(duì)象的類,。

2. objc_class中的isa指的是類的元類。

3. superClass是一層層集成的,,到最后NSObject的superClass是nil,。而NSObject的isa指向根元類,這個(gè)根元類的isa指向它自己,,而它的superClass是NSObject,也就是最后形成一個(gè)環(huán),。

4. metaClass也是相互繼承的。

5. 從objc_class結(jié)構(gòu)體可以看出來,,里面有個(gè)isa屬性,,還有個(gè)super_class屬性,它倆都是指針,,其實(shí)在objc_class的定義中也能看出來,,每一個(gè)objc_class都有isa,但是不一定會(huì)有super_class。

重點(diǎn)總結(jié):

meta-class也是一個(gè)類,,也可以向它發(fā)送一個(gè)消息,,那么它的isa又是指向什么呢,?為了不讓這種結(jié)構(gòu)無限延伸下去,Objective-C的設(shè)計(jì)者讓所有的meta-class的isa指向基類的meta-class,,以此作為它們的所屬類。即,,任何NSObject繼承體系下的meta-class都使用NSObject的meta-class作為自己的所屬類,而基類的meta-class的isa指針是指向它自己,。這樣就形成了一個(gè)完美的閉環(huán),。

方法在 objc-runtime-new.h中定義:

struct method_t { SEL name; const char *types; IMP imp; struct SortBySELAddress : public std::binary_function { bool operator() (const method_t& lhs, const method_t& rhs) { return lhs.name < rhs.name;="" }="">

我們說下上面代碼中的SEL和IMP,。

SEL:表示該方法的名稱,, IMP: 指向該方法的具體實(shí)現(xiàn)的函數(shù)指針。

SEL 的含義:

typedef struct objc_selector *SEL;

它是一個(gè)指向 objc_selector 指針,,表示方法的名字/簽名,。如下所示,打印出 selector,,會(huì)打印出來方法的名稱。

不同類的實(shí)例對(duì)象performSelector相同的 selector 時(shí),,會(huì)在各自的消息選標(biāo)(selector)/實(shí)現(xiàn)地址(address) 方法鏈表中根據(jù) selector 去查找具體的方法實(shí)現(xiàn)IMP, 然后用這個(gè)方法實(shí)現(xiàn)去執(zhí)行具體的實(shí)現(xiàn)代碼,。這是一個(gè)動(dòng)態(tài)綁定的過程,在編譯的時(shí)候,,我們不知道最終會(huì)執(zhí)行哪一些代碼,,只有在執(zhí)行的時(shí)候,通過selector去查詢,,我們才能確定具體的執(zhí)行代碼,。

IMP 的含義:

在前面我們也看到 IMP 的定義為:

typedef id (*IMP)(id, SEL, ...);

id是一個(gè)指向 objc_object 結(jié)構(gòu)體的指針,任何繼承自 NSObject 的類對(duì)象都可以用id 來指代,,因?yàn)?NSObject 的第一個(gè)成員實(shí)例就是isa,。

IMP 是一個(gè)函數(shù)指針,這個(gè)被指向的函數(shù)包含一個(gè)接收消息的對(duì)象id(self 指針), 調(diào)用方法的選標(biāo) SEL (方法名),,以及不定個(gè)數(shù)的方法參數(shù),,并返回一個(gè)id。也就是說 IMP 是消息最終調(diào)用的執(zhí)行代碼,是方法真正的實(shí)現(xiàn)代碼 ,。我們可以像在C語言里面一樣使用這個(gè)函數(shù)指針,。

NSObject 類中的methodForSelector:方法就是這樣一個(gè)獲取指向方法實(shí)現(xiàn)IMP 的指針,methodForSelector:返回的指針和賦值的變量類型必須完全一致,,包括方法的參數(shù)類型和返回值類型,。

IMP實(shí)際上是一個(gè)函數(shù)指針,指向方法實(shí)現(xiàn)的地址,。

Method用于表示類定義中的方法,,則定義如下:

typedef struct objc_method *Methodstruct objc_method{ SEL method_name OBJC2_UNAVAILABLE; // 方法名 char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; // 方法實(shí)現(xiàn)}

我們可以看到該結(jié)構(gòu)體中包含一個(gè)SEL和IMP,實(shí)際上相當(dāng)于在SEL和IMP之間作了一個(gè)映射,。有了SEL,,我們便可以找到對(duì)應(yīng)的IMP,從而調(diào)用方法的實(shí)現(xiàn)代碼,。

iOS 運(yùn)行時(shí)(Runtime)之 類和對(duì)象

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多