Swift與Objective-C的動態性分析
Objective-C最大的特性無疑是其的動態性,可以利用OC的動態效能夠獲得一個類的方法和屬性,從而實現靈活的程式,但Swift是否也包含了runtime機制呢?
下面我們將從純Swift的類和繼承OC的Swift類來闡述Swift的runtime機制。
用例分析:
1、獲取類的方法,屬性
Swift的類:TestASwithClass
Objective-C的類:TestSwiftClass繼承UIViewController繼承NSObject
動態性最重要的一點就是拿到某個類的方法和屬性,使用如下的方法列印類的方法和屬性
提供出來測試TestASwithClass、TestSwiftClass類的測試函式(方法):
呼叫showClsRuntime列印方法
列印如下:
結果分析:
對於純Swift的TestASwithClass來說任何方法、屬性都未獲取到。
對於TestSwiftClass來說除testReturnTuple、testReturnVoidWithaCharacter兩個方法外,其他的都獲取成功了。
這是為什麼呢?
1:純Swift類的函式呼叫已經不是OC那樣的執行時訊息了,而是類似C++似得vtable,在編譯時就確定了呼叫那個函式了。
2:而TestSwiftClass繼承自UIViewController也就是NSObject,Swift為了相容OC,所以繼承自NSObject的類都保留了他的動態性,所以我們能通過runtime拿到他的屬性和方法。
可是為什麼testReturnTuple、testReturnVoidWithaCharacter這兩個函式卻無法通過runtime獲得呢?
從OC的動態特性可知,所有執行時方法都依賴TypeEcoding,也就是method_getTypeEncoding函式,它指定了引數型別以及引數在入棧時的記憶體空間,沒有這個標識則沒法入棧.而元祖,和字元型別是Swift獨有的,所以不能利用runtime獲得他的方法。
2、方法替代
動態性最常用的方法就是方法替代,將某個類的方法替代為自定義的方法,從而起到hook的作用。
對於純Swift類(如TestASwithClass)來說,無法通過objc runtime替換方法,因為由上面的測試可知拿不到這些方法、屬性
對於繼承自NSObject類(如TestSwiftVC)來說,無法通過runtime獲取到的方法肯定沒法替換了。那能通過runtime獲取到的方法就都能被替換嗎?我們測一把
Method Swizzling的程式碼如下:
找到官方文件讀讀。
@objc
可以知道@objc是用來將Swift的API匯出給Objective-C和Objective-C runtime使用的,如果你的類繼承自Objective-c的類(如NSObject)將會自動被編譯器插入@objc標識。
我們在把TestASwiftClass(純Swift類)的方法、屬性前都加個@objc 試試
文件裡還有一句說明:
dynamic
加了@objc標識的方法、屬性無法保證都會被執行時呼叫,因為Swift會做靜態優化。要想完全被動態呼叫,必須使用dynamic修飾。使用dynamic修飾將會隱式的加上@objc標識。
這也就解釋了為什麼testReturnVoidWithaId無法被替換,因為寫在Swift裡的程式碼直接被編譯優化成靜態呼叫了。
而viewDidAppear是繼承Objective-C類獲得的方法,本身就被修飾為dynamic,所以能被動態替換。
相關文章
- Objective-C 的動態提示和技巧Object
- [譯] Swift 中的動態特性Swift
- Swift學習: 從 Objective-C 到 SwiftSwiftObject
- 從Objective-C到SwiftObjectSwift
- 動態規劃的理解與案例分析動態規劃
- Swift vs Objective-C:未來看好 Swift 的十個理由SwiftObject
- Objective-C 動態特性應用指南Object
- Objective-C和Swift混編ObjectSwift
- Swift vs. Objective-C:未來看好 Swift 的十個理由SwiftObject
- 製作 Swift 和 Objective-C Mixed 的 PodSwiftObject
- Swift專案中呼叫Objective-C的庫SwiftObject
- 來一次有側重點的區分Swift與Objective-CSwiftObject
- Swift和Objective-C混合程式設計——Swift呼叫OCSwiftObject程式設計
- Swift和Objective-C混合程式設計——OC呼叫SwiftSwiftObject程式設計
- Swift如何呼叫Objective-C程式碼SwiftObjectC程式
- Swift 幾種動態判斷類的方法Swift
- iOS動態性iOS
- 替代Objective-C?Swift尚不成熟ObjectSwift
- Swift 呼叫 Objective-C 的可變引數函式SwiftObject函式
- Swift 在對 Objective-C 改進的 6 個方面SwiftObject
- 猿題庫從 Objective-C 到 Swift 的遷移ObjectSwift
- Objective-C Runtime 之動態方法解析實踐Object
- Swift 中的屬性Swift
- dtrace動態分析
- 我是直接學Swift還是Objective-C?SwiftObject
- Laravel 動態屬性的實現Laravel
- 優雅的開發 Swift 和 Objective-C 混編的 FrameworkSwiftObjectFramework
- 【iOS開發黑科技】與tableViewDelegate,tableViewDataSource說再見,Objective-C,Swift雙版本...iOSViewObjectSwift
- 實戰iOS-objectivec&swift靜態程式碼分析iOSObjectSwift
- Swift 開屏廣告的實現 (支援本地與網路的圖片,動態圖,視訊)Swift
- React原始碼分析與實現(二):狀態、屬性更新 -> setStateReact原始碼
- 我應該直接學Swift還是Objective-C?SwiftObject
- 動態規劃-----線性動態規劃
- JavaScript 靜態屬性與靜態方法JavaScript
- IOS Objective-C屬性解析iOSObject
- 動態規劃分析動態規劃
- swift中的名稱空間及動態載入類Swift
- Objective-C 和 Swift 混編專案的小 Tips(一)ObjectSwift