iOS Runtime 實踐(1)

發表於2016-07-02

iOS Runtime

很多時候我們都在看iOS開發中的黑魔法——Runtime。懂很多,但如何實踐卻少有人提及。本文便是iOS Runtime的實踐第一篇。

WebView

我們這次的實踐主題,是使用針對介面程式設計的方式,藉助Excalibur系統,來達到動態切換UIWebViewWKWebkit的目的。
為什麼要動態切換?其實我們眾所周知,Apple的UIWebView存在巨大的記憶體洩漏。當網頁內容較複雜,圖片較大時,經常會出現150MB+的記憶體佔用率;並且這個記憶體佔用率會一直存在無法消除。雖然StackOverflow上有很多大神想出了各種方式,但作用卻很小。
Apple 從 iOS8 開始,推出了更新、優化更好的WKWebkit。這個庫是UIWebView的繼承者,在相同的瀏覽頁面下,WKWebKit提供的WKWebView的記憶體佔用率甚至可以只有UIWebView1/10。可惜的是,我們很多時候為了保證使用者的覆蓋率,target iOS Version都是 iOS7。這時候我們就需要使用UIWebView來達到顯示的目的。
那麼問題來了,如何實現根據iOS版本來達到動態載入的目的呢?

Excalibur

Excalibur是我們用來對映和字串scheme對應關係的類。通過註冊scheme對應的類,來達到目的。
註冊一個類:

Excalibur中獲取scheme指定的

通過Excalibur,我們使用哪個,就可以在Runtime時期才確定。

針對介面程式設計

在設計模式上,我們經常聽到說,要針對介面程式設計。那麼在iOS開發中,怎樣才算是針對介面程式設計呢?這個又有什麼好處呢?
Objective-C語言中,我們一般認為Protocol便是介面功能的協議。
這裡,我們想達到的目的,是在不同的iOS版本下,呼叫不同的Webkit來進行網頁渲染。而網頁的渲染一般放在一個ViewController下,因此我們可以針對這個需求,制訂一個用來渲染指定URLViewController介面:

這裡的介面,返回一個ViewController,該VC可以用來開啟url網頁。
現在我們可以寫兩個ViewController,分別是DWKWebViewControllerDWKWebkitViewController;其中DWKWebViewController使用UIWebView來渲染網頁:

DWKWebkitViewController則使用WKWebView來渲染網頁:

接下來,二者在Runtime的初始化階段向Excalibur註冊自己:

DWKWebViewController

DWKWebkitViewController

那麼,8.0以下時,DWKWebViewController就會是DWK_MODULE_WEB_VC模組的實現者;而在8.0及其以上時,DWKWebkitViewController則是DWK_MODULE_WEB_VC模組的實現者。

呼叫

做好了以上兩步準備,接下來便是呼叫DWK_MODULE_WEB_VC的模組來渲染網頁了。
這裡,我們已經約定好,實現DWK_MODULE_WEB_VCViewController肯定會實現DWKProtocol,因此我們可以這樣來獲取我們想要的ViewController Class

總結

至此,使用Runtime達到動態載入UIWebViewWKWebkit的目的達成。

程式碼連結

我把程式碼放到了Github上,希望對你有所幫助:

如果有問題,還請留言。

相關文章