Swift與Objective-C的動態(tài)性分析

Objective-C最大的特性無疑是其的動態(tài)性,可以利用OC的動態(tài)性能夠獲得一個類的方法和屬性,從而實現(xiàn)靈活的程序,但Swift是否也包含了runtime機制呢?

下面我們將從純Swift的類和繼承OC的Swift類來闡述Swift的runtime機制。


用例分析:

1、獲取類的方法,屬性

Swift的類:TestASwithClass

TestASwithClass 純Swift類

Objective-C的類:TestSwiftClass繼承UIViewController繼承NSObject

TestSwiftClass OC類

動態(tài)性最重要的一點就是拿到某個類的方法和屬性,使用如下的方法打印類的方法和屬性

提供出來測試TestASwithClass著瓶、TestSwiftClass類的測試函數(shù)(方法):

測試函數(shù)

調(diào)用showClsRuntime打印方法

調(diào)用showClsRuntime

打印如下:

測試結(jié)果

結(jié)果分析:

對于純Swift的TestASwithClass來說任何方法漂彤、屬性都未獲取到。

對于TestSwiftClass來說除testReturnTuple梢什、testReturnVoidWithaCharacter兩個方法外,其他的都獲取成功了。

這是為什么呢?

1:純Swift類的函數(shù)調(diào)用已經(jīng)不是OC那樣的運行時消息了,而是類似C++似得vtable,在編譯時就確定了調(diào)用那個函數(shù)了壶笼。

2:而TestSwiftClass繼承自UIViewController也就是NSObject,Swift為了兼容OC,所以繼承自NSObject的類都保留了他的動態(tài)性,所以我們能通過runtime拿到他的屬性和方法。

可是為什么testReturnTuple雁刷、testReturnVoidWithaCharacter這兩個函數(shù)卻無法通過runtime獲得呢?

從OC的動態(tài)特性可知,所有運行時方法都依賴TypeEcoding,也就是method_getTypeEncoding函數(shù),它指定了參數(shù)類型以及參數(shù)在入棧時的內(nèi)存空間,沒有這個標識則沒法入棧.而元祖,和字符類型是Swift獨有的,所以不能利用runtime獲得他的方法覆劈。


2、方法替代

動態(tài)性最常用的方法就是方法替代,將某個類的方法替代為自定義的方法,從而起到hook的作用沛励。

對于純Swift類(如TestASwithClass)來說责语,無法通過objc runtime替換方法,因為由上面的測試可知拿不到這些方法目派、屬性

對于繼承自NSObject類(如TestSwiftVC)來說坤候,無法通過runtime獲取到的方法肯定沒法替換了。那能通過runtime獲取到的方法就都能被替換嗎企蹭?我們測一把

Method Swizzling的代碼如下:

Method Swizzling

找到官方文檔讀讀白筹。

@objc

可以知道@objc是用來將Swift的API導出給Objective-C和Objective-C runtime使用的智末,如果你的類繼承自O(shè)bjective-c的類(如NSObject)將會自動被編譯器插入@objc標識。

我們在把TestASwiftClass(純Swift類)的方法徒河、屬性前都加個@objc 試試

文檔里還有一句說明:

dynamic

加了@objc標識的方法系馆、屬性無法保證都會被運行時調(diào)用,因為Swift會做靜態(tài)優(yōu)化虚青。要想完全被動態(tài)調(diào)用它呀,必須使用dynamic修飾。使用dynamic修飾將會隱式的加上@objc標識棒厘。

這也就解釋了為什么testReturnVoidWithaId無法被替換纵穿,因為寫在Swift里的代碼直接被編譯優(yōu)化成靜態(tài)調(diào)用了。

而viewDidAppear是繼承Objective-C類獲得的方法奢人,本身就被修飾為dynamic谓媒,所以能被動態(tài)替換。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末何乎,一起剝皮案震驚了整個濱河市句惯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌支救,老刑警劉巖抢野,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異各墨,居然都是意外死亡指孤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門贬堵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恃轩,“玉大人,你說我怎么就攤上這事黎做〔骢耍” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵蒸殿,是天一觀的道長筷厘。 經(jīng)常有香客問我,道長宏所,這世上最難降的妖魔是什么酥艳? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮楣铁,結(jié)果婚禮上玖雁,老公的妹妹穿的比我還像新娘更扁。我一直安慰自己盖腕,他們只是感情好赫冬,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溃列,像睡著了一般劲厌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上听隐,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天补鼻,我揣著相機與錄音,去河邊找鬼雅任。 笑死风范,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的沪么。 我是一名探鬼主播硼婿,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼禽车!你這毒婦竟也來了寇漫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤殉摔,失蹤者是張志新(化名)和其女友劉穎州胳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逸月,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡栓撞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了彻采。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腐缤。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肛响,靈堂內(nèi)的尸體忽然破棺而出岭粤,到底是詐尸還是另有隱情,我是刑警寧澤特笋,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布剃浇,位于F島的核電站,受9級特大地震影響猎物,放射性物質(zhì)發(fā)生泄漏虎囚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一蔫磨、第九天 我趴在偏房一處隱蔽的房頂上張望淘讥。 院中可真熱鬧,春花似錦堤如、人聲如沸蒲列。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝗岖。三九已至侥猩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抵赢,已是汗流浹背欺劳。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铅鲤,地道東北人划提。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像邢享,于是被迫代替她去往敵國和親腔剂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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