通常你們都用 JSPatch?前端
用別人的,總很差。老王造了個輪子,我來描述一下。git
怎麼設計這個 Patch?github
Patch 主要是 幹什麼的呢?
通常大公司的 App 在運行的過程中,業務線很是複雜,可能會出現一些問題。後端
能夠遠端下發一個文件,開發的 App 經過 加載 這個文件,
實行 這個 代碼 補丁。app
OC 能夠的,由於是動態語言,有 runtime ,因此才能搞這個 patch。函數
OC 有本身的消息轉發流程。 Runtime 有 objc_msgSend
和 _objc_msgForward
。
Runtime 有這兩個方法,
這兩個函數特性,讓全部的函數調用都會走這兩個方法。優化
這樣 app 中有一個 context, 能夠執行用於 patch 的語言。lua
本文中的 iOS 補丁方案直接運用 這個 JavaScriptCore,
就是使用 JavaScriptCore 提供的 JSContext.
能讓 JavaScript 語言 和 Objective-C 之間,有一個接口。而後就能夠 JavaScript 與 Objective-C 相互調用了。
( 蘋果本身實現的 )設計
FFI, Foreign Function Interface ,就是把一個語言暴露出來的接口,能讓其餘語言來調用。
Java 的 JNI 標準,與 FFI 比較類似。
FFI ,首先聽從 Coding Convention ,就是定義遵照一些調用的協議和規定。
爲何要有 FFI 呢?指針
咱們執行一個函數調用,首先開闢一個棧幀,這個棧幀傳遞一些什麼樣的參數?參數的類型是什麼?參數 的個數,是多少?包括這個函數裏面,執行的一些動做是什麼?
FFI 就把遵照的一些調用的協議和規定定義出來。
老王 Patch 庫的這個自定義 FFI , 就是把想作的 patch 語言, 對接 Objective-C 的執行環境。
須要往裏面傳遞的命令,把這個東西,給規定出來。
使用 JSPatch 的過程中,老王發現,用的很是的不順手,
爲何他不順手呢?
老王覺得,JSPatch 把 JavaScript 硬生轉換成至關於 Objective-C 這種風格的,補丁代碼。
其間,還作了不少的語言處理,包括 Bang 說的源函數的處理。
包括 C 語言函數,相似 Ruby 的 Method Mission .
至於其餘, 老王覺得, JSPatch 都是在後端進行的。
要增強Patch, 自己具備的語言的一個平滑性,就是寫 JavaScript , 就使用 JavaScript 的寫法
把 JavaScriptContext 的註冊接口,抽象出三個層,
define, 往 Objective-C 發消息。 不須要參數返回, 能夠用 define .
須要定義的,確定都本身定義的。
抽象出這一層,就能夠了。
須要一個返回值的時候,使用
去執行一些什麼任務
老王感受蘋果封裝的 JavaScriptContext,可能有一些問題。
好比說, 傳遞的一些函數對象,開發者封裝了兩層。那就可能獲取不到這個對象了。
這個時候, 須要 Callback 方式,在那個執行環境當中,獲取前端的 function 內容。
用 JavaScriptCore 相關的一種回調方式,來取到在當前 JavaScriptContext 環境 當中的一個 function 值。
這個 patch ,是幹什麼的? 對所使用的內容, 有哪些指令?
經過 這些指令,咱們能夠實現, 想要 patch 到的一些功能
對於 Objective-C 中的 self 關鍵字, 一般用來表明當前對象的指針。
還須要改 super 關鍵字, 爲 oc_super. 由於 super 在 ECMAScript 6 裏面, 也是關鍵字了,須要迴避掉。
original, 是 Patch 中特有的。調用以前的函數,即打補丁以前的這個函數的調用。
對 JavaScript 高階函數作一個平滑處理,不然可能寫起來,很是費勁。
a.request( function(a:id,b:Int):double{}, callback:(string,string) => int, (num1:string, num2:double) => { return num1 + num2; } );
request 方法, 有三個參數。三個 function 類型的參數。第一個 function 函數,接收兩個參數。第二個參數 callback, 是咱們在函數調用上下文中取到的。第三個參數是, ECMAScript 6 中使用的箭頭函數。
最好呢,對這個進行一些支持。
這些操做,是經過預處理的方式,
編譯成,可以對接 OC 的 Block 指令的。
而後,才能 正常 完成工做。
你們都仿照 JSPatch,在 JavaScriptContext 中註冊一大堆本身要進行 patch 的函數。
想要用到什麼,就去補充什麼。
通常都是徹底借鑑 Bang 的一些想法。
Github 官方 repo 連接:https://github.com/wangyunico...
個人民間 repo , https://github.com/BoxDengJZ/...