1. 程式人生 > >【unity】【jit】【遊戲開發】講解ios系統不支援JIT的來龍去脈,以及unity在IOS上需要使用反射時候的替代方案

【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 就到這裡,高手繞路,喜歡點贊,最好有評論哦,謝謝大家

不要不要的