共用方式為


iOS 和 Mac Catalyst 上的原生 AOT 部署

原生 AOT 部署會在 iOS 和 Mac Catalyst 上產生 .NET 多平臺應用程式 UI (.NET MAUI) 應用程式,該應用程式已預先編譯為機器碼(AOT)。 原生 AOT 會執行靜態程式分析、完整修剪您的應用程式,這會積極移除未以靜態方式參考的程式代碼,以及預先產生程式代碼。

發佈和部署原生 AOT 應用程式會產生下列優點:

  • 減少應用程式套件大小。
  • 啟動時間更快。
  • 建置時間更快。

原生 AOT 將會對 .NET 運行時間的某些層面的使用造成限制,而且應該只在應用程式大小和效能很重要的案例中使用。 其會要求您將應用程式調整為原生 AOT 需求,這表示確保它們完全修剪且 AOT 相容。 如需原生 AOT 限制的詳細資訊,請參閱 原生 AOT 限制

啟用原生 AOT 部署時,建置系統會分析您的程式代碼及其所有相依性,以確認它是否適合完整修剪和 AOT 編譯。 如果偵測到不相容,就會產生修剪和 AOT 警告。 單一修剪或 AOT 警告表示應用程式與原生 AOT 部署不相容,而且可能無法正常運作。 因此,建置原生 AOT 部署的應用程式時,您應該檢閱並更正所有修剪和 AOT 警告。 若無法這麼做,可能會導致運行時間發生例外狀況,因為可能已移除必要的程序代碼。 如果您隱藏警告,則必須徹底測試 AOT 部署的應用程式,以確認尚未從未嘗試的應用程式變更功能。 如需詳細資訊,請參閱 修剪警告 簡介和 AOT 警告簡介。

注意

在某些情況下,修正修剪和 AOT 警告是不可能的,例如第三方連結庫發生時。 在這種情況下,必須更新第三方連結庫,才能完全相容。

原生 AOT 效能優點

發佈和部署原生 AOT 應用程式會產生通常小於 2.5 倍的應用程式,而啟動的應用程式通常快 2 倍。 不過,確切的效能優點取決於多種因素,包括正在使用的平臺、執行應用程式的裝置,以及應用程式本身。

重要

下圖顯示 iOS 和 Mac Catalyst 上應用程式原生 AOT 部署的典型 dotnet new maui 效能優點。 不過,確切的數據與硬體相依,未來版本可能會變更。

下圖顯示不同部署模型中 iOS 和 Mac Catalyst 上應用程式的應用程式套件大小 dotnet new maui

圖表顯示不同部署模型的應用程式套件大小。

上圖顯示,相較於預設部署模型,原生 AOT 通常會針對 iOS 和 Mac Catalyst 產生超過 2 倍以上的應用程式。

下圖顯示 iOS 和 Mac Catalyst on Mono 和 Native AOT 部署上應用程式的特定硬體 dotnet new maui 平均啟動時間:

顯示Mono和Native AOT 上平均應用程式啟動時程的圖表。

上圖顯示,相較於Mono部署,原生 AOT 通常會在iOS裝置上擁有高達2倍的啟動時間,以及Mac Catalyst上啟動時間快1.2倍。

下圖顯示 iOS 和 Mac Catalyst 上應用程式在不同部署模型中的特定硬體 dotnet new maui 上的平均建置時間:

顯示Mono和Native AOT 上平均應用程式建置時間的圖表。

上圖顯示,相較於預設部署模型,原生 AOT 在 iOS 裝置上的建置時間通常高達 2.8 倍。 針對 Mac Catalyst,組建時間與 arm64 單一 RID 應用程式相當,但與 Mono 部署相比,通用應用程式的建置時間會稍微慢一點。

重要

在許多情況下,原生 AOT 會產生更小且更快的應用程式。 不過,在某些情況下,原生 AOT 可能不會產生更小且更快的應用程式。 因此,請務必測試和分析您的應用程式,以判斷啟用原生 AOT 部署的結果。

使用原生 AOT 發佈

原生 AOT 部署模型會使用 $(PublishAot) 組建屬性和 dotnet publish 命令來啟用。 下列範例示範如何修改項目檔,以在iOS和Mac Catalyst上啟用原生 AOT 部署:

<PropertyGroup>
  <!-- enable trimming and AOT analyzers on all platforms -->
  <IsAotCompatible>true</IsAotCompatible>

  <!-- select platforms to use with NativeAOT -->
  <PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">true</PublishAot>
  <PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">true</PublishAot>
</PropertyGroup>

針對所有平臺,將 $(IsAotCompatible) build屬性設定為 true,即可進行修剪和AOT分析器。 這些分析器可協助您識別與修剪或 AOT 不相容的程式代碼。

針對 iOS 和 Mac Catalyst,有條件地設定 $(PublishAot)true,可在發行期間建置和原生 AOT 編譯期間啟用動態程式碼使用分析。 原生 AOT 分析包含應用程式的所有程式代碼,以及應用程式相依的任何連結庫。

警告

$(PublishAot)建置屬性不應該受到組建組態的條件。 這是因為修剪功能參數會根據建置屬性的值 $(PublishAot) 啟用或停用,而且所有建置組態中都應該啟用或停用相同的功能,讓您的程式碼運作方式相同。 如需修剪功能參數的詳細資訊,請參閱 修剪功能參數

驗證原生 AOT 應用程式是否正常運作的唯一方式,是使用 dotnet publish 發佈它,並確認您的程式代碼及其相依性不會產生任何修剪或 AOT 警告。 特別是, dotnet build -t:Publish 不等於 dotnet publish

使用下列 dotnet publish 命令,使用原生 AOT 部署在 iOS 和 Mac Catalyst 上發布您的應用程式:

# iOS
dotnet publish -f net9.0-ios -r ios-arm64

# Mac Catalyst
dotnet publish -f net9.0-maccatalyst -r maccatalyst-arm64
dotnet publish -f net9.0-maccatalyst -r maccatalyst-x64

# Universal Mac Catalyst apps
# (when <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> is set in the project file)
dotnet publish -f net9.0-maccatalyst

提示

經常發佈應用程式,以在開發生命週期早期探索修剪或 AOT 問題。

原生 AOT 限制

原生 AOT 將會對 .NET 運行時間的某些層面的使用造成限制,而且應該只在應用程式大小和效能很重要的案例中使用。 其會要求您調整應用程式以符合原生 AOT 需求,這表示確保它們完全修剪且 AOT 相容,這可能需要大量工作。 除了原生 AOT 部署.NET 限制之外,.NET MAUI 的原生 AOT 部署也有其他限制。

應用程式相依的第三方連結庫可能與 AOT 不相容。 確保連結庫修剪且 AOT 相容的唯一方法是使用原生 AOT 部署和 dotnet publish 命令發布您的應用程式,並查看原生 AOT 編譯程式是否產生連結庫的任何警告。 如需建立您自己的連結庫 AOT 相容的詳細資訊,請參閱 如何讓連結庫與原生 AOT 相容。

反映和動態程序代碼

原生 AOT 部署會限制在您的程式代碼及其相依性中使用反映,而且可能需要使用註釋來協助原生 AOT 編譯程式瞭解反映模式。 當編譯程式遇到無法以靜態方式分析的反映模式時,因此無法建置應用程式,它會產生修剪警告。 原生 AOT 也會防止您在應用程式中使用動態程式代碼。 例如,編譯 System.Linq.Expressions 無法如預期般運作,而且無法在運行時間載入和執行元件。 當編譯程式遇到無法預先編譯的動態模式時,它會產生 AOT 警告。

在 .NET MAUI 應用程式中,這表示:

重要

Mono 解釋器與原生 AOT 部署不相容,因此 $(UseInterpreter) $(MtouchInterpreter) 和 MSBuild 屬性在使用原生 AOT 時沒有作用。 如需Mono解釋器的詳細資訊,請參閱 iOS和Mac Catalyst上的Mono解釋器

如需修剪警告的詳細資訊,請參閱 修剪警告簡介。 如需 AOT 警告的詳細資訊,請參閱 AOT 警告簡介。

將應用程式調整為原生 AOT 部署

使用下列檢查清單可協助您將應用程式調整為原生 AOT 部署需求:

  • 確定已編譯所有 XAML:
    • 拿掉所有 [XamlCompilation(XamlCompilationOptions.Skip)] 使用量。
    • 拿掉所有 <?xaml-comp compile="false" ?> 使用量。
  • 拿掉對 LoadFromXaml 方法的所有呼叫。
  • 請確定已編譯所有數據系結。 如需詳細資訊,請參閱 編譯的系結。
    • 請確定所有 XAML 資料系結都會以 x:DataType標註。
    • 確定所有程式代碼數據系結都會以 Lambda 型系結取代所有以字串為基礎的系結。
  • [QueryProperty(...)]將所有使用方式取代為 介面的實作IQueryAttributable。 如需詳細資訊,請參閱 使用單一方法處理導覽數據。
  • 以取代所有 SearchHandler.DisplayMemberName 使用方式 ItemTemplate。 如需詳細資訊,請參閱 定義搜尋結果項目外觀
  • 將 XAML 中使用的型別的所有隱含轉換運算子取代為 TypeConverter,並使用 將它附加至您的型 TypeConverterAttribute別。 如需詳細資訊,請參閱 定義 TypeConverter 以取代隱含轉換運算符
    • 從類型 A 轉換成類型 B時, ConvertTo 將會使用與 A 相關聯之類型轉換子上的方法,或是 ConvertFrom 使用與 B 相關聯之類型轉換子上的方法。
    • 當來源和目標型別都有相關聯的型別轉換器時,可以使用其中一個。
  • 使用來源產生器編譯所有正則表達式。 如需詳細資訊,請參閱 .NET 規則運算式來源產生器
  • 確定 JSON 串行化和還原串行化使用來源產生的內容。 如需詳細資訊,請參閱 最小 API 和 JSON 承載
  • 檢閱並更正任何修剪或 AOT 警告。 如需詳細資訊,請參閱 修剪警告 簡介和 AOT 警告簡介。
  • 徹底測試您的應用程式。

iOS 和 Mac Catalyst 上的原生 AOT 診斷支援

原生 AOT 和 Mono 共用診斷和檢測功能的子集。 由於Mono的診斷工具範圍,在Mono內診斷和偵錯問題會很有説明,而不是原生 AOT。 修剪和 AOT 相容的應用程式不應該有行為差異,因此調查通常適用於這兩個運行時間。

下表顯示 iOS 和 Mac Catalyst 上原生 AOT 的診斷支援:

功能 完全支援 部分支援 不支援
可檢視性和遙測 部分支援
開發時間診斷 完全支援
原生偵錯 部分支援
CPU 分析 部分支援
堆積分析 不支援

下列各節提供此診斷支援的其他資訊。

可檢視性和遙測

透過 dotnet-dsrouter 來追蹤行動平臺上的 .NET MAUI 應用程式,透過 TCP/IP,將診斷工具與在 iOS 和 Mac Catalyst 上執行的 .NET 應用程式連線。 不過,原生 AOT 目前與此案例不相容,因為它不支援使用 TCP/IP 堆棧建置的 EventPipe/DiagnosticServer 元件。 可檢視性仍可在程式碼中明確達成。

開發時間診斷

.NET CLI 工具提供 和 publish的個別命令builddotnet build (或在 Start Debugging (F5) Visual Studio Code 中,在建置或啟動 .NET MAUI iOS 或 Mac Catalyst 應用程式時,預設會使用 Mono。 只有在專案檔中啟用此部署模型時,才會dotnet publish建立原生 AOT 應用程式。

並非所有診斷工具都能順暢地與已發佈的原生 AOT 應用程式搭配運作。 不過,所有修剪和 AOT 相容的應用程式(也就是,在建置時間不會產生任何修剪和 AOT 警告的應用程式)都不應該在 Mono 和 Native AOT 之間發生行為差異。 因此,行動應用程式開發周期期間,所有 .NET 開發時間診斷工具,例如 熱重新載入,仍可供開發人員使用。

提示

您應該如往常一樣開發、偵錯及測試您的應用程式,並使用 Native AOT 發佈最終應用程式作為最後一個步驟之一。

原生偵錯

當您在開發期間執行 .NET MAUI iOS 或 Mac Catalyst 應用程式時,預設會在 Mono 上執行。 不過,如果在專案檔中啟用原生 AOT 部署,當應用程式未在建置階段產生任何修剪和 AOT 警告時,在 Mono 和 Native AOT 之間預期行為會相同。 如果您的應用程式符合此需求,您可以使用標準的 Visual Studio Code Managed 偵錯引擎進行開發和測試,

發佈之後,原生 AOT 應用程式是真正的原生二進位檔,因此 Managed 調試程式將無法處理它們。 不過,原生 AOT 編譯程式會產生您可以使用 lldb偵錯的完整原生可執行檔。 使用 lldb 對 Mac Catalyst 應用程式進行偵錯是直接的,因為它會在相同的系統上執行。 不過,偵錯 NativeAOT iOS 應用程式需要額外的工作。

使用原生 AOT 對 .NET MAUI iOS 應用程式進行偵錯

與原生 AOT 相容的 .NET MAUI iOS 應用程式,且已使用此部署模型正確設定和發佈,可以進行偵錯,如下所示:

  1. 使用原生 AOT 目標 ios-arm64 發佈您的應用程式,並記下下列資訊:

    • 應用程式名稱(如下所述 <app-name>)。
    • 套件組合標識碼(如下 <bundle-identifier>所述)。
    • 已發行應用程式封存 .ipa 檔案的路徑(如下所述 <path-to-ipa>)。
  2. 取得您的實體裝置識別碼(如下所示 <device-identifier>):

    xcrun devicectl list devices
    
  3. 在實體裝置上安裝應用程式:

    xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
    
  4. 在您的實體裝置上啟動應用程式:

    xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
    
  5. 開啟 lldb 並連線到您的實體裝置:

    (lldb) device select <device-identifier>
    (lldb) device process attach -n <app-name>
    

成功完成這些步驟之後,您將能夠使用 lldb開始對原生 AOT .NET MAUI iOS 應用程式進行偵錯。

符號檔案的重要性

根據預設,偵錯符號會從應用程式的二進位檔分割成 .dSYM 檔案。 調試程式和驗屍分析工具會使用此檔案來顯示局部變數、來源行號的相關信息,以及重新建立損毀傾印的堆棧追蹤。 因此,在將應用程式提交至 App Store 之前,請務必保留符號檔。

CPU 分析

Xcode Instruments 可用來收集原生 AOT 應用程式的 CPU 樣本。

堆積分析

原生 AOT 目前不支持堆積分析。

另請參閱