Unity 托管代碼剝離

如果項目很大,代碼量很多滴劲,不僅會使包體變大攻晒,編譯時間變長,還會導致各種編譯報錯班挖。比如:

ARM64 branch out of range (154869072 max is +/-128MB)

Unity提供了一種被稱作托管代碼剝離( managed code stripping )的方案用來刪除未使用或無法訪問的代碼鲁捏。托管代碼剝離從托管程序集中刪除代碼,包括從項目中的 C# 腳本構建的程序集萧芙、作為包和插件一部分的程序集给梅,以及 .NET Framework 中的程序集假丧。

Unity 使用稱為 Unity 鏈接器(Unity linker)的工具對項目程序集中的代碼執(zhí)行靜態(tài)分析。靜態(tài)分析識別在執(zhí)行期間無法訪問的任何類动羽、類的部分包帚、函數(shù)或函數(shù)的部分。此分析僅包括構建時存在的代碼运吓,因為在 Unity 執(zhí)行靜態(tài)分析時不存在運行時生成的代碼渴邦。可以使用 **托管剝離級別 **來控制剝離的程度拘哨。

配置托管代碼剝離:

配置托管代碼剝離
  1. 轉到編輯 > 項目設置 > 播放器几莽。
  2. 在其他設置中,找到優(yōu)化一欄宅静。
  3. 將 Managed Stripping Level 屬性設置為所需的值章蚣。
屬性 功能
Disabled 不會移除任何代碼。如果使用 mono ,這是默認設置
Minimal 只在 UnityEngine 和 .net 類庫中搜索未使用的代碼姨夹。不會刪除任何用戶編寫的代碼纤垂。此設置最不可能導致任何意外的運行時行為如果使用 IL2CPP ,這是默認設置磷账。
Low Unity會搜索一些用戶編寫的程序集,以及所有 UnityEngine和 .net 類庫來尋找未使用的代碼峭沦。此設置應用一組規(guī)則,這些規(guī)則刪除一些未使用的代碼逃糟,但將意外后果的可能性降到最低吼鱼,例如使用反射的運行時代碼的行為更改。
Medium Unity 部分搜索所有程序集以查找無法訪問的代碼绰咽。此設置應用一組規(guī)則菇肃,這些規(guī)則剝離更多類型的代碼模式以減少構建大小。盡管 Unity 不會刪除所有可能無法訪問的代碼取募,但此設置確實會增加發(fā)生不良或意外行為更改的風險琐谤。
High Unity會對所有程序集進行廣泛搜索,以找到無法訪問的代碼玩敏。在這個設置中斗忌,Unity優(yōu)先考慮的是減少大小,而不是代碼穩(wěn)定性旺聚,并刪除盡可能多的代碼织阳。這種搜索可能比較低的剝離級別花費更長的時間。徹底測試你的應用砰粹,仔細使用[Preserve]屬性和link.xml文件唧躲,以確保Unity鏈接器不會剝離關鍵代碼。

使用 托管代碼剝離 需謹慎,防止必要的代碼被剝離惊窖。我們可以使用 Preserve 或 Link.xml 來保護代碼。

Preserve
可以使用 Preserve 來防止 Unity 鏈接器剝離代碼的特定部分厘贼。如果您的應用程序生成 Unity 執(zhí)行靜態(tài)分析時不存在的運行時代碼界酒,這將很有幫助;例如嘴秸,通過反射毁欣。Preserve 要么為 Unity 鏈接器提供關于它不應該剝離哪些代碼模式的一般指導,要么提供不剝離特定的岳掐、已定義的代碼部分的指令凭疮。

例如:

class Foo
{
    [Preserve]
    public void PreservedMethod(){}
}

Link.xml
也可以在項目中包括一個名為 link.xml 的 .xml 文件,以保留特定程序集或程序集的一部分的列表串述。xml 文件必須存在于 Assets 文件夾或項目中的 Assets 文件夾的子目錄中执解,并且文件中必須包含 <linker> 標記。Unity 鏈接器將保存在 link.xml 文件中的任何程序集纲酗、類型或成員視為根類型衰腌。

例如:

<linker>
  <!--Preserve types and members in an assembly-->
  <assembly fullname="AssemblyName">
    <!--Preserve an entire type-->
    <type fullname="AssemblyName.MethodName" preserve="all"/>

    <!--No "preserve" attribute and no members specified means preserve all members-->
    <type fullname="AssemblyName.MethodName"/>

    <!--Preserve all fields on a type-->
    <type fullname="AssemblyName.MethodName" preserve="fields"/>

    <!--Preserve all fields on a type-->
    <type fullname="AssemblyName.MethodName" preserve="methods"/>

    <!--Preserve the type only-->
    <type fullname="AssemblyName.MethodName" preserve="nothing"/>

    <!--Preserving only specific members of a type-->
    <type fullname="AssemblyName.MethodName">
        
      <!--Fields-->
      <field signature="System.Int32 FieldName" />

      <!--Preserve a field by name rather than signature-->
      <field name="FieldName" />
      
      <!--Methods-->
      <method signature="System.Void MethodName()" />

      <!--Preserve a method with parameters-->
      <method signature="System.Void MethodName(System.Int32,System.String)" />

      <!--Preserve a method by name rather than signature-->
      <method name="MethodName" />

      <!--Properties-->

      <!--Preserve a property, it's backing field (if present), 
          getter, and setter methods-->
      <property signature="System.Int32 PropertyName" />

      <property signature="System.Int32 PropertyName" accessors="all" />

      <!--Preserve a property, it's backing field (if present), and getter method-->
      <property signature="System.Int32 PropertyName" accessors="get" />

      <!--Preserve a property, it's backing field (if present), and setter method-->
      <property signature="System.Int32 PropertyName" accessors="set" />

      <!--Preserve a property by name rather than signature-->
      <property name="PropertyName" />

      <!--Events-->

      <!--Preserve an event, it's backing field (if present), add, and remove methods-->
      <event signature="System.EventHandler EventName" />

      <!--Preserve an event by name rather than signature-->
      <event name="EventName" />

    </type>
  </assembly>
</linker>

詳細請參考 Unity 官方文檔:

https://docs.unity.cn/cn/current/Manual/ManagedCodeStripping.html

如果你做了托管代碼剝離,但是在IOS還是會報ARM64 branch out of range觅赊,那么 你可以打開Xcode工程進行如下設置:


優(yōu)化等級設為 -Os

把主工程和UnityFramework工程的優(yōu)化等級都設為 -Os


環(huán)境:
Unity:2021.3.2
Xcode:13.3.1

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末右蕊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吮螺,更是在濱河造成了極大的恐慌饶囚,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸠补,死亡現(xiàn)場離奇詭異萝风,居然都是意外死亡,警方通過查閱死者的電腦和手機紫岩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門闹丐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人被因,你說我怎么就攤上這事卿拴。” “怎么了梨与?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵堕花,是天一觀的道長。 經(jīng)常有香客問我粥鞋,道長缘挽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮壕曼,結果婚禮上苏研,老公的妹妹穿的比我還像新娘。我一直安慰自己腮郊,他們只是感情好摹蘑,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著轧飞,像睡著了一般衅鹿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上过咬,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天大渤,我揣著相機與錄音,去河邊找鬼掸绞。 笑死泵三,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的衔掸。 我是一名探鬼主播切黔,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼具篇!你這毒婦竟也來了纬霞?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤驱显,失蹤者是張志新(化名)和其女友劉穎诗芜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埃疫,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡伏恐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了栓霜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翠桦。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖胳蛮,靈堂內(nèi)的尸體忽然破棺而出销凑,到底是詐尸還是另有隱情,我是刑警寧澤仅炊,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布斗幼,位于F島的核電站,受9級特大地震影響抚垄,放射性物質發(fā)生泄漏蜕窿。R本人自食惡果不足惜谋逻,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桐经。 院中可真熱鬧毁兆,春花似錦、人聲如沸阴挣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屯吊。三九已至送巡,卻和暖如春摹菠,著一層夾襖步出監(jiān)牢的瞬間盒卸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工次氨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔽介,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓煮寡,卻偏偏與公主長得像虹蓄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子幸撕,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 最近網(wǎng)友通過網(wǎng)站搜索Unity3D在手機及其他平臺下占用內(nèi)存太大. 這里寫下關于unity3d對于內(nèi)存的管理與優(yōu)化...
    楊樹葉的楊閱讀 1,066評論 0 0
  • 之前說過薇组,JSON .NET For Unity具有比JsonFx For Unity3D更好的平臺兼容性,所以這...
    HelloWorld_de97閱讀 4,320評論 0 1
  • 面試題總分類 --------------------------------------- |--繼承,封裝,多...
    浪蕩少年閱讀 8,336評論 0 8
  • 用到的組件 1坐儿、通過CocoaPods安裝 2律胀、第三方類庫安裝 3、第三方服務 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,602評論 1 180
  • 一:什么是協(xié)同程序貌矿?答:在主線程運行時同時開啟另一段邏輯處理炭菌,來協(xié)助當前程序的執(zhí)行。換句話說逛漫,開啟協(xié)程就是開啟一個...
    CrixalisAs閱讀 2,059評論 1 7