Runtime 源碼解析之對(duì)象創(chuàng)建

寫在前面

稍微了解OC運(yùn)行時(shí)機(jī)制的人應(yīng)該都知道:

1. 類和對(duì)象都是id,在給你一個(gè)id的前提下無法直觀的知道這個(gè)對(duì)象是類對(duì)象還是類本身冒窍。簡單的可以簡化成runtime管理的都是id (id的本質(zhì)其實(shí)是objc_object甥绿, objc_class頭部其實(shí)就是id, 也就是isa)。

2. Class在objc中是動(dòng)態(tài)創(chuàng)建的脚囊,selector, method桐磁, imp悔耘,protocol等都是隨后綁定上去的(即所謂的運(yùn)行時(shí)綁定)。

3. 通過runtime能夠查出當(dāng)前運(yùn)行時(shí)環(huán)境中所有的類我擂,每個(gè)類中的方法衬以,每個(gè)類消息的綁定,每個(gè)類的實(shí)現(xiàn)的協(xié)議校摩,每個(gè)協(xié)議的定義看峻,每個(gè)類當(dāng)前的消息緩存等一切你想知道的東西。

4. 類的方法(消息)調(diào)用是間接的衙吩。

正文

好的互妓,在我們知道上述知識(shí)以后。我們來研究下,在不存在NSObject的情況下冯勉,怎樣動(dòng)態(tài)創(chuàng)建一個(gè)類澈蚌。

動(dòng)態(tài)創(chuàng)建類

圖中幾個(gè)方法的用法和作用不再贅述,不清楚的可以自行查閱官方文檔灼狰。有一點(diǎn)需要注意宛瞄,我們?nèi)潭疾荒苁褂?ARC,因?yàn)?ARC 模式下從void *轉(zhuǎn)換到id是需要有一個(gè) bridge 的過程交胚,而這個(gè)過程仍然依賴于NSObject完成份汗,所以我們又會(huì)陷入一個(gè)需要NSObject的死循環(huán)。

運(yùn)行起來會(huì)報(bào)以下錯(cuò)誤:

運(yùn)行報(bào)錯(cuò)

查看文檔得知承绸,每當(dāng)一個(gè)無效Selector被發(fā)出并沒有得到響應(yīng)裸影,運(yùn)行時(shí)系統(tǒng)將調(diào)用doesNotRecognizeSelector:,該方法執(zhí)行后會(huì)引發(fā)NSInvalidArgumentException军熏,并生成錯(cuò)誤消息轩猩。那好吧,check一下荡澎。

實(shí)現(xiàn)方法

再次運(yùn)行均践。。摩幔。

未實(shí)現(xiàn)initialize方法

我們似乎忘了實(shí)現(xiàn)initialize方法彤委。。或衡。該方法會(huì)在某個(gè)類第一次被初始化時(shí)調(diào)用焦影,加上它。

實(shí)現(xiàn)initialize方法

再run一次

未實(shí)現(xiàn)alloc方法

額封断,alloc類方法是如何實(shí)現(xiàn)的斯辰?這個(gè)時(shí)候,我們就需要下載Runtime源碼一探究竟了坡疼。彬呻。。

我們知道柄瑰,在OC中闸氮,任何類都是繼承自NSObject這一基類。這么一說教沾,alloc類方法應(yīng)該也是NSobject實(shí)現(xiàn)的蒲跨。

我們打開源碼,,找到NSObject.mm這個(gè)文件授翻,并通過導(dǎo)航菜單快讀定位到alloc方法的位置

alloc方法

按住 ? 一路點(diǎn)擊跟蹤财骨,直到這里:

callAlloc

我們發(fā)現(xiàn)镐作,在Objc2.0之后新增了一種自定義的快捷構(gòu)造方法藏姐。但是殊途同歸隆箩,事實(shí)上它們最終都要調(diào)用class_createInstance這個(gè)方法,我們來看看:

class_createInstance

在老的源碼中羔杨,這里會(huì)判斷是否使用GC捌臊。iOS上是不能使用GC的,這是為Mac設(shè)計(jì)的兜材,既然新版本去掉這個(gè)判斷理澎,我們也就沒有必要去理會(huì)了。繼續(xù)跟蹤曙寡,我們來到了_class_createInstanceFromZone函數(shù):

_class_createInstanceFromZone

在這里糠爬,runtime主要做了有關(guān)內(nèi)存對(duì)齊的一些計(jì)算,由于zone是nil举庶,這里直接用calloc申請(qǐng)了一塊內(nèi)存执隧。calloc 與 malloc 的區(qū)別,可以自行谷歌户侥。

好的镀琉,接下來就剩最后一步了,objc_constructInstance函數(shù):

objc_constructInstance

這里回歸了我們一開始說的蕊唐,對(duì)象的isa指針屋摔。我們也說了,id的本質(zhì)其實(shí)是objc_object替梨,那么objc_object到底是什么:

objc_object

objc_object其實(shí)就是一個(gè)C++結(jié)構(gòu)體钓试,有權(quán)限控制,有成員函數(shù)副瀑。通過我們剛才提到的objc_object::initIsa函數(shù)弓熏,可以知道,就是把對(duì)象的isa指針指向這個(gè)類的元信息Class俗扇。

objc_object::initIsa

看到這里硝烂,我們其實(shí)就已經(jīng)可以為我們的類寫一個(gè)alloc方法了。但是似乎有個(gè)問題無法解決铜幽,objc_object對(duì)于開發(fā)者而言并不能接觸到滞谢,我們有必要通過直接修改內(nèi)存的方式去修改其isa變量。那么除抛,回到源碼狮杨,我們看看isa那個(gè)isa_t類型究竟是什么:

isa_t

可以發(fā)現(xiàn),它是個(gè)聯(lián)合體到忽。從源碼中我們也可以看到橄教,它在初始化的時(shí)候直接被當(dāng)做uintptr_t對(duì)待清寇,而uintptr_t又是unsigned long的typedef,所以我們可以寫出如下代碼:

alloc

好了护蝶,把實(shí)現(xiàn)的alloc方法添加到我們的類中华烟,然后用初始化一個(gè)實(shí)例對(duì)象,再執(zhí)行持灰。

大功告成
運(yùn)行結(jié)果

到此為止盔夜,在不存在NSObject的情況下,動(dòng)態(tài)創(chuàng)建一個(gè)類的工作完成了堤魁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喂链,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子妥泉,更是在濱河造成了極大的恐慌椭微,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盲链,死亡現(xiàn)場離奇詭異蝇率,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)匈仗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門瓢剿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悠轩,你說我怎么就攤上這事间狂。” “怎么了火架?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵鉴象,是天一觀的道長。 經(jīng)常有香客問我何鸡,道長纺弊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任骡男,我火速辦了婚禮淆游,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隔盛。我一直安慰自己犹菱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布吮炕。 她就那樣靜靜地躺著腊脱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪龙亲。 梳的紋絲不亂的頭發(fā)上陕凹,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天悍抑,我揣著相機(jī)與錄音,去河邊找鬼杜耙。 笑死搜骡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泥技。 我是一名探鬼主播浆兰,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼珊豹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起榕订,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤店茶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后劫恒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贩幻,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年两嘴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丛楚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡憔辫,死狀恐怖趣些,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贰您,我是刑警寧澤坏平,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站锦亦,受9級(jí)特大地震影響舶替,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杠园,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一顾瞪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抛蚁,春花似錦陈醒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亲配,卻和暖如春尘应,著一層夾襖步出監(jiān)牢的瞬間惶凝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工犬钢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苍鲜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓玷犹,卻偏偏與公主長得像混滔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歹颓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉坯屿,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,690評(píng)論 0 9
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動(dòng)態(tài)語言,它將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,222評(píng)論 1 5
  • Objective-C語言是一門動(dòng)態(tài)語言巍扛,他將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事情放到了運(yùn)行時(shí)來處理领跛。這種動(dòng)態(tài)語言...
    tigger丨閱讀 1,390評(píng)論 0 8
  • 我們常常會(huì)聽說 Objective-C 是一門動(dòng)態(tài)語言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢撤奸?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,182評(píng)論 0 7
  • 文中的實(shí)驗(yàn)代碼我放在了這個(gè)項(xiàng)目中吠昭。 以下內(nèi)容是我通過整理[這篇博客] (http://yulingtianxia....
    茗涙閱讀 914評(píng)論 0 6