Swift類與結(jié)構(gòu)體(下)

一.異變方法

? ? ? Swift中class和struct都能定義方法撤嫩,但在默認(rèn)情況下廉侧,值類型(struct)屬性不能被自身的實(shí)例方法修改,如果想被修改啤握,需要加關(guān)鍵字mutating關(guān)鍵字來(lái)修飾,下圖就是為了驗(yàn)證

圖1未加mutating
圖2加mutating

通過(guò)SIL文件進(jìn)行對(duì)比,不加mutating的晶框,默認(rèn)傳入的self的point是一個(gè)結(jié)構(gòu)體實(shí)例排抬,是一個(gè)值(是一個(gè)let的常量),而加了mutating之后授段,默認(rèn)傳入的self是一個(gè)地址蹲蒲,會(huì)有一個(gè)@inout修飾,接收的是一個(gè)地址(還是一個(gè)var類型的變量)侵贵。

相關(guān)資料截圖:

圖3SIL文件


圖4異變案例

結(jié)論:從兩幅圖里可以看出届搁,在struct結(jié)構(gòu)體里,相同的方法窍育,分別進(jìn)行編譯卡睦,在沒(méi)有加mutating時(shí),會(huì)報(bào)錯(cuò)漱抓,添加了mutating關(guān)鍵字后就是編譯成功的表锻,這是因?yàn)樵趍utating編譯之后,傳入的self會(huì)被標(biāo)記為inout參數(shù)乞娄,無(wú)論在mutating方法內(nèi)部發(fā)生了什么瞬逊,都會(huì)影響外部依賴類型的一切。這也就是異變方法的本質(zhì)仪或。

順帶說(shuō)下 inout 這個(gè)關(guān)鍵字确镊,輸入輸出參數(shù),如果我們想函數(shù)能夠修改一個(gè)形式參數(shù)(用_表示范删,代表是一個(gè)let類型的常量蕾域,也不能被修改)的值,而且希望這些改變?cè)诤瘮?shù)結(jié)束之后依然有效到旦,那么就需要將形式參數(shù)定義為 輸入輸出形式參數(shù)束铭,在形式參數(shù)定義開(kāi)始的時(shí)候在前邊添加一個(gè)inout關(guān)鍵字可以定義一個(gè)輸入輸出形式參數(shù)。

二.方法調(diào)度

方法調(diào)度也就是消息轉(zhuǎn)發(fā)厢绝,在Object-C中契沫,是通過(guò)objc_msgSend進(jìn)行消息轉(zhuǎn)發(fā)的,Swift中是通過(guò)靜態(tài)派發(fā)和函數(shù)表派發(fā)進(jìn)行調(diào)度的昔汉。

什么時(shí)候用靜態(tài)派發(fā)懈万,什么時(shí)候用函數(shù)表派發(fā)拴清,如下圖:

圖5方法調(diào)度

通過(guò)匯編分析得知,在class,struct,enum中会通,函數(shù)的調(diào)用過(guò)程為 :找到metadata口予,確定函數(shù)的地址(metadata(相當(dāng)于ISA指針) + 偏移量(aslr)),執(zhí)行函數(shù)基于函數(shù)表的調(diào)度涕侈,而這個(gè)函數(shù)表又在typeDescriptor里沪停,typeDescriptor是對(duì)class,struct裳涛,enum分別的詳細(xì)描述木张。

圖5函數(shù)的執(zhí)行過(guò)程
圖6函數(shù)表存在位置

那么函數(shù)表是如何排列的呢?是通過(guò)Mach-O來(lái)分析的端三,Mach-O的全稱是Mach Object 文件格式的縮寫舷礼,是MAc或者iOS上可執(zhí)行文件的格式,類似于Windows上PE格式郊闯,Linux上的ELF格式妻献,常見(jiàn)的可執(zhí)行文件格式有.a ,.o ,.dylib,framework,dyld,.dsym.

Mach-O的文件格式:

圖7Mach-O
圖8header區(qū)(是二進(jìn)制的)
圖9load commands區(qū)
圖10data區(qū)(存放的是匯編指令)
圖11存放位置
圖12 函數(shù)在內(nèi)存中的地址

三.影響函數(shù)派發(fā)的方式

static ?靜態(tài)派發(fā)

圖13影響函數(shù)派發(fā)方式

注意:

1.final:實(shí)際開(kāi)發(fā)過(guò)程中,方法团赁,類不需要被重載育拨,添加final關(guān)鍵字

圖14?final

2.dynamic:對(duì)于一個(gè)class中的函數(shù)添加了dynamic,具有了動(dòng)態(tài)性欢摄,可以動(dòng)態(tài)替換此方法至朗,如果是一個(gè)struct中的函數(shù)添加了dynamic,具有了動(dòng)態(tài)性剧浸,但還是靜態(tài)派發(fā)锹引,只是把方法替換調(diào)用而已。(SwiftUI 里經(jīng)常出現(xiàn)唆香,以及@_dynamicReplacement)

圖15?dynamic

在原生的Swift里嫌变,是沒(méi)有runtime的,要想也具有runtime性質(zhì)躬它,可以用關(guān)鍵字組合 objc +?dynamic

3.@objc +?dynamic組合腾啥,具有消息調(diào)度機(jī)制,可以使用黑魔法(也就是runtime的API)冯吓,但是這樣OC里仍然不能直接調(diào)用到Swift中的此方法(圖16倘待,19),如何查看呢组贺,請(qǐng)看截圖(圖17凸舵,18):

圖16
圖17
圖18
圖19
圖20 使用runtime
圖21交互后的結(jié)果

四.函數(shù)內(nèi)聯(lián)

圖22 函數(shù)內(nèi)聯(lián)

如果對(duì)象只在聲明的文件中可見(jiàn),可以用private或fileprivate進(jìn)行修飾失尖。編譯器會(huì)對(duì)private或fileprivate對(duì)象進(jìn)行檢查啊奄,確保沒(méi)有其他繼承關(guān)系的情形下渐苏,自動(dòng)打上final,進(jìn)而使得對(duì)象獲得靜態(tài)派發(fā)的特性


fileprivate: 只允許在定義源文件中訪問(wèn)

private:定義的聲明中訪問(wèn)

圖23 實(shí)例代碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載菇夸,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者琼富。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市庄新,隨后出現(xiàn)的幾起案子鞠眉,更是在濱河造成了極大的恐慌,老刑警劉巖择诈,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件械蹋,死亡現(xiàn)場(chǎng)離奇詭異颠猴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)婴削,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門玛迄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人哪痰,你說(shuō)我怎么就攤上這事。” “怎么了步做?”我有些...
    開(kāi)封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奈附。 經(jīng)常有香客問(wèn)我全度,道長(zhǎng),這世上最難降的妖魔是什么斥滤? 我笑而不...
    開(kāi)封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任将鸵,我火速辦了婚禮,結(jié)果婚禮上佑颇,老公的妹妹穿的比我還像新娘顶掉。我一直安慰自己,他們只是感情好挑胸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布痒筒。 她就那樣靜靜地躺著,像睡著了一般茬贵。 火紅的嫁衣襯著肌膚如雪簿透。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天解藻,我揣著相機(jī)與錄音老充,去河邊找鬼。 笑死螟左,一個(gè)胖子當(dāng)著我的面吹牛戳粒,可吹牛的內(nèi)容都是我干的蔚约。 我是一名探鬼主播涂籽,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼树枫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砂轻!你這毒婦竟也來(lái)了斤吐?” 一聲冷哼從身側(cè)響起和措,我...
    開(kāi)封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诬留,失蹤者是張志新(化名)和其女友劉穎贫母,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绿贞,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡樟蠕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年靠柑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歼冰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甸怕,死狀恐怖梢杭,靈堂內(nèi)的尸體忽然破棺而出武契,到底是詐尸還是另有隱情咒唆,我是刑警寧澤全释,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布妄迁,位于F島的核電站,受9級(jí)特大地震影響判族,放射性物質(zhì)發(fā)生泄漏项戴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一周叮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧界斜,春花似錦、人聲如沸各薇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)开缎。三九已至,卻和暖如春林螃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疗认。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谨设,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓鹏秋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子百拓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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