Unity中使用Strip的總結


參考鏈接:

Unity-Managed code stripping

Unity-Managed bytecode stripping with IL2CPP

簡而言之,Code Strip就是代碼裁剪。開啟代碼裁剪,能夠在build時將項目中沒有用到的代碼裁減掉,以減少build出的代碼量。

如果使用了il2cpp,由于build過程中先生成CIL然后再生成cpp代碼。所以開啟Managed code stripping之后,能減少CIL的生成,從而加快cpp生成的過程。

Strip的主要作用在于裁剪系統庫、Unity引擎代碼、插件代碼,往往它們包含了大量對工程無用的代碼。

開啟方法

在Unity編輯器的File->Build Settings->Player Settings可以設置Managed Stripping Level。


Managed Stripping Level

(PC平臺)有4個選項可供選擇:Disable(默認),Low,Medium,High。

(iOS平臺)沒有Disable選項,默認為Low,但提供了Strip Engine Code的選項。

各個Level對不同代碼的裁剪規則不同,具體內容可以看上面第一個鏈接。

強制保留

因為UnityLinker進行strip的邏輯原因,代碼中使用反射調用(沒有直接引用)的類和屬性等也會被裁剪掉,這樣會導致運行時錯誤。

Unity提供了兩種方法來標記需要強制保留的代碼:

  1. 使用[Preserve]標簽,可以對Assembly、Type、Field、Properties、Method使用。
  2. 使用Link.xml文件,在文件中寫明需要保留的代碼,使用范圍同上,還可以標記保留整個Namespace。

對比

這里使用新工程做一個測試,對新工程設置不同的strip level,然后在iOS平臺build出xCode工程。對比xCode工程的Classes/Native中代碼的數量:

  • low:72.7M(74項)


    low
  • high:54.5M(62項)


    high

strip中遇到的問題及解決方法

類型轉換錯誤

InvalidCastException: Unable to cast object of type 'BehaviourTree' to type 'DialogueTree'.

對于該類型錯誤,無法有效的確定錯誤原因(以NodeCanvas為例,對錯誤的實例進行類型轉換的邏輯流程無法準確定位,可能與NodeCanvas對行為樹資源反序列化的實現有關),最直接的辦法是將整個模塊的Namespace包含到link中以避免此類問題。
(同時可以對官方示例進行同等級的strip,嘗試更仔細的解決問題,通常官方示例因為體量小,能更快的進行build迭代和測試)。

無法為抽象類創建對象

Exception: Cannot create an instance of an interface or abstract type for NodeCanvas.Framework.ActionTask。

通常原因在于其實現類沒有被保留下來。報錯定位依然不明確。解決辦法同上.

無法解析符號

Type with name 'NodeCanvas.Tasks.Actions.PlayerActions.AnimationAction' could not be resolved.

其中指出的符號,即類型、方法、屬性等,因為沒有被保留下來,導致進行反射調用時無法確定符號意義導致的問題。解決方法很明確,就是將符號寫入link.xml以在strip過程中保留。

找不到Class ID對應的類型

ReportException: UnityLogError Could not produce class with ID 134.

通常是因為Unity引擎的代碼被Strip掉了,導致在程序運行時找不到對應的類。對此類問題比較方便的一點在于,錯誤信息給出了具體的類(https://docs.unity3d.com/Manual/ClassIDReference.html),要解決問題只需要將查表找到的Class加入到link.xml即可。
如果在文檔中無法找到對應的class,這里還有另外一種辦法,參考Could not produce class with ID 363

找不到構造器

ReflectionException: The reflector requires concrete classes.Type XXX has no constructor. Is it an interface?

這是在使用StrangeIOC框架時遇到的問題。因為框架通過注入->反射來獲取具體類型的實例,所以其中的Mediator、Model、Command、Service都沒有直接引用(在MVCSContext中會進行綁定,以此為根可以找到所有的MVCS類),在strip時由于沒有自定義的構造器,導致錯誤(原因待查)。解決該問題的方式,就是不通過UnityLinker的邏輯來strip這些類,而是將這些類所在的Namespace加入到link.xml。

找不到set函數

ReportException: UnityLogError System.ArgumentException: Set Method not found for 'xxx'

這也是在使用StrangeIOC框架時遇到的問題。因為我們在Mediator、Service類的開頭使用[Inject]標簽來獲取一個Model,而且在邏輯處理部分只用到了屬性的get方法,如果這個Mediator、Service本身沒有被完整保留(添加到Link.xml或者使用了[Preserve]標簽),這樣會導致該條屬性的set方法被裁剪掉,初始化這個類時,會因為找不到屬性的set方法而報錯。
(代碼示例:)

[Inject]
public MyModel myModel {get; set;}

此時解決辦法之一是將這個Mediator、Service類加入到Link.xml中,在Strip時完整保留這個類。還有另一個小技巧:讓Inject繼承PreserveAttribute,這樣能保證所有使用[Inject]標簽的屬性都被完整保留下來。

strip之后需要注意的問題

  1. 務必做全量測試。雖然部分插件對Strip做了處理(例如提供了link.xml),但是依然有許多插件、第三方庫沒有考慮Strip的問題。所以必須通過全量測試來保證沒有過度裁剪。
  2. 維護好邏輯代碼。通常邏輯代碼不需要進行裁剪,但是對于某些特殊情況(大量出現一部分代碼僅運行在PC平臺,另一部分代碼需要運行在各個平臺)最好是對代碼合理分配Namespace,以便于在link.xml中通過Namespace進行裁剪。

問題及參考資料

  1. 目前沒有找到能夠查看Strip過程裁剪掉(或保留)內容的方法。

Unity strip engine code 遇到執行不能之問題與解決

il2cpp減代碼體積, strip byte code以及strip engine code相關問題

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容