【unity】【jit】【遊戲開發】講解ios系統不支援JIT的來龍去脈,以及unity在IOS上需要使用反射時候的替代方案
標題有點長啊,很彪,所以我們叫彪題(咋地,東北地,你瞅啥)
1.帶有增高墊IL的c#
c#語言作為一種高階語言,是不能直接在我們的CPU上來直接執行的。
需要編譯成IL語言(Intermediate Language)即中間層語言(就是這麼高冷)。然後由我們的編譯器編譯成
底層的語言來到cpu執行。IL是將.NET程式碼轉化為機器語言的一箇中間語言,因此又把IL語言稱之為偽組合語言。
使用中間語言的優點有兩點,一是可以實現平臺無關性,既與特定CPU無關;二是提高了靈活性。
2.ios編譯機制
當unity工程在ios平臺打包的時候,我們會注意到,當你從MAC上的unity匯出的功能中有幾個檔案的名字
一il2cpp開頭,這是什麼鬼。我們來推理一下,cpp是c++檔案的字尾,il是中間層語言,2就是to,那就是吧il轉化成c++用的東西啊!
不管怎樣,我們知道,我們做的c#最終要變成c++的程式碼了,看起來沒什麼問題。而當你在你的unity中做一個反射的時候,編譯就會報錯。
3.為啥IOS不支援jit
JIT(just
in time)他不但會生成新的程式碼,而且會執行新的程式碼,我擦。。。。寫個病毒進去不是得上天了。
說到jit,我們就不得不聊聊aot(靜態編譯),Java是支援JIT的,c/c++都是需要本地編譯完成後,然後執行編譯後的檔案,即靜態編譯方式,所以我們要動態的改變程式碼是不可能的,所以c#做出的JIT在il2cpp的時候是過不了的。
PS:某年的安全大會上黑現場觀眾的手機 ios和wp 被黑的機率很低,安卓很高正是因為如此,ios和wp都不支援動態編譯所以程式釋放新程式碼病毒啥的也就不可能了。
4.需要使用JIT的時候的替代方案
前幾天後端和我反映,公會系統執行時候的欄位同步有點消耗資源,因為我們把公會相關的欄位都寫在了玩家身上一起,每次請求的時候都會全部同步,本身公會的資料量又相對較大。我們只想同步哪些被改變的欄位,沒有被改變的不要同步。
我們第一個想到的是做一個反射,但是ios上又不支援反射,我們採取了另外一種方案————if else
public void updateData(Guild backdata) { if (backdata.CheckResetValue("position")) { this.position = backdata.position; } if (backdata.CheckResetValue("gold")) { this.gold = backdata.gold; } if (backdata.CheckResetValue("guildId")) { this.guildId = backdata.guildId; } if (backdata.CheckResetValue("canJoinGuildAt")) { this.canJoinGuildAt = backdata.canJoinGuildAt; } if (backdata.CheckResetValue("hasRead")) { this.hasRead = backdata.hasRead; } if (backdata.CheckResetValue("dailyContributionXp")) { this.dailyContributionXp = backdata.dailyContributionXp; } if (backdata.CheckResetValue("totalContributionXp")) { this.totalContributionXp = backdata.totalContributionXp; } if (backdata.CheckResetValue("maxContributionCount")) { this.maxContributionCount = backdata.maxContributionCount; } if (backdata.CheckResetValue("dailyContributionCount")) { this.dailyContributionCount = backdata.dailyContributionCount; }
}
我只貼出一部分
就這樣後端發來一個string型的list,和需要同步的欄位,前端用ifelse進行比對,來同步改變的欄位,這樣後端不用同步所有的欄位了,降低了後端的壓力,同事前端的效率也大大加快。(好像很傻比,但是很有效)。
ok 就到這裡,高手繞路,喜歡點贊,最好有評論哦,謝謝大家
不要不要的