Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В нативном развертывании AOT создается приложение .NET Multi-platform App UI (.NET MAUI) для iOS и Mac Catalyst, которое перед временем выполнения (AOT) компилируется в нативный код. Родной AOT выполняет статический анализ программы, полную обрезку приложения, что агрессивно удаляет код, на который нет статических ссылок, и предварительную генерацию кода.
Публикация и развертывание собственного приложения AOT дает следующие преимущества:
- Уменьшен размер пакета приложения.
- Быстрое время запуска.
- Более быстрое время сборки.
Собственный AOT вводит ограничения на использование определенных аспектов среды выполнения .NET и должен использоваться только в сценариях, когда размер приложения и производительность важны. Вам потребуется адаптировать приложения к собственным требованиям AOT, что означает, что они полностью обрезаны и совместимы с AOT. Дополнительные сведения об ограничениях Native AOT см. в разделе Ограничения Native AOT.
Если развертывание Native AOT включено, система сборки анализирует ваш код и все его зависимости, чтобы проверить, подходят ли они для полного тримминга и AOT-компиляции. При обнаружении несовместимости создаются предупреждения обрезки и предупреждения AOT. Одно сообщение об обрезке или AOT сигнализирует, что приложение несовместимо с развёртыванием Native AOT и может функционировать неправильно. Поэтому при создании приложения для развертывания Native AOT следует проверять и исправлять все предупреждения, связанные с удалением ненужных компонентов и AOT. Сбой этого может привести к исключениям во время выполнения, так как необходимый код мог быть удален. Если вы подавляете предупреждения, развернутое приложение AOT, необходимо тщательно протестировать, чтобы убедиться, что функциональность не изменилась с нетримированного приложения. Дополнительные сведения см. в разделе "Введение в предупреждения об обрезке" и "Введение в предупреждения AOT".
Примечание.
Могут быть случаи, когда исправление обрезки и предупреждений AOT невозможно, такие как когда они возникают в сторонних библиотеках. В таких случаях сторонние библиотеки должны быть обновлены для полной совместимости.
Преимущества производительности при использовании AOT-компиляции
Публикация и развертывание приложения Native AOT создаёт приложение, которое обычно в 2,5 раза меньше по размеру и запускается до 2 раз быстрее. Однако точные преимущества производительности зависят от нескольких факторов, которые включают используемую платформу, устройство, на котором работает приложение, и само приложение.
Внимание
На следующих диаграммах показаны типичные преимущества производительности развертывания Native AOT для dotnet new maui приложения в iOS и Mac Catalyst. Однако точные данные зависят от оборудования и могут измениться в будущих выпусках.
На следующей dotnet new maui диаграмме показан размер пакета приложения для приложения в iOS и Mac Catalyst в разных моделях развертывания:
На предыдущей диаграмме показано, что, как правило, Native AOT создает более 2x небольших приложений для iOS и Mac Catalyst по сравнению с моделью развертывания по умолчанию.
На следующей диаграмме показано среднее время запуска приложения dotnet new maui на конкретном оборудовании для iOS и Mac Catalyst при развертывании через Mono и Native AOT:
На приведенной выше диаграмме показано, что собственный AOT обычно обеспечивает до двухкратного ускорения запуска на устройствах iOS и на 20% быстрее запуска в Mac Catalyst по сравнению с развертыванием Mono.
На следующей диаграмме показано среднее время сборки для конкретного dotnet new maui оборудования для приложения в iOS и Mac Catalyst в разных моделях развертывания:
На предыдущей диаграмме показано, что обычно нативный AOT обеспечивает скорость сборки до 2,8 раза быстрее на устройствах iOS по сравнению с моделью развертывания по умолчанию. Для Mac Catalyst время сборки сравнимо с приложениями arm64 single RID, но немного медленнее для универсальных приложений по сравнению с развертыванием Mono.
Внимание
Во многих сценариях Native AOT будет создавать более компактные и быстрые приложения. Однако в некоторых сценариях независимый AOT может не создавать меньшие и более быстрые приложения. Поэтому важно протестировать и профилировать приложение, чтобы определить результат включения нативного (Native) развертывания AOT.
Публикация с помощью Native AOT
Модель развертывания родного AOT включается со свойством сборки $(PublishAot) и командой dotnet publish. В следующем примере показано, как изменить файл проекта, чтобы включить развертывание Native AOT в iOS и Mac Catalyst:
<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) в true для всех платформ включает поддержку тримминга и анализаторов AOT. Эти анализаторы помогают определить код, несовместимый с оптимизацией (trimming) или AOT.
Условное задание $(PublishAot) значения true для iOS и Mac Catalyst позволяет выполнить динамический анализ использования кода во время сборки и компиляцию машинного Native AOT во время публикации. Анализ нативного AOT включает весь код приложения и все библиотеки, от которых зависит приложение.
Предупреждение
Свойство $(PublishAot) сборки не должно быть обусловлено конфигурацией сборки. Это связано с тем, что параметры обрезки включены или отключены на основе значения $(PublishAot) свойства сборки, а те же функции должны быть включены или отключены во всех конфигурациях сборки, чтобы код вел себя одинаково. Дополнительные сведения об обрезке переключателей функций см. в разделе "Параметры обрезки".
Единственный способ проверить, что Native AOT приложение работает правильно, - это опубликовать его с помощью dotnet publish и убедиться, что ни ваш код, ни его зависимости не создают предупреждений о тримминге или AOT. В частности, dotnet build -t:Publish не эквивалентен dotnet publish.
Используйте следующую dotnet publish команду для публикации приложения на iOS и Mac Catalyst с использованием развертывания Native AOT:
# 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, и это может потребовать значительных усилий. Помимо ограничений .NET для развертывания Native AOT, развертывание Native AOT для .NET MAUI имеет дополнительные ограничения.
Сторонние библиотеки, от которые зависят ваши приложения, могут быть несовместимы с AOT. Единственный способ убедиться, что библиотека совместима с обрезкой и AOT, заключается в публикации приложения с использованием собственного развертывания AOT и команды dotnet publish, чтобы выяснить, выдает ли компилятор Native AOT какие-либо предупреждения для этой библиотеки. Сведения о том, как сделать собственные библиотеки совместимыми с AOT, см. в статье о том, как сделать библиотеки совместимыми с собственным AOT.
Отражение и динамический код
Нативное развертывание AOT ограничивает использование отражения в вашем коде и его зависимостях, и может стать необходимым использование аннотаций, чтобы помочь Native AOT компилятору понять шаблоны отражения. Когда компилятор сталкивается с паттерном рефлексии, который он не может статически проанализировать и, следовательно, не может создать приложение, он создает предупреждения о тримминге. Собственный AOT также запрещает использование динамического кода в приложении. Например, компиляция System.Linq.Expressions не будет работать должным образом, и невозможно загрузить и выполнить сборки во время выполнения. Когда компилятор сталкивается с динамическим паттерном, который не может быть скомпилирован заранее, он создаст предупреждение AOT.
В приложении .NET MAUI это означает следующее:
- Весь XAML должен быть скомпилирован заранее. Поэтому убедитесь, что вы не отключили компиляцию XAML и что все привязки компилируются. Дополнительные сведения см. в разделе "Компиляция XAML" и "Скомпилированные привязки".
- Все выражения привязки должны использовать скомпилированные привязки, а не путь привязки, заданный строкой. Дополнительные сведения см. в разделе "Скомпилированные привязки".
- Операторы неявного преобразования могут не вызываться при назначении значения несовместимого типа свойству в XAML или при использовании привязки данных двумя свойствами разных типов. Вместо этого вы должны определить TypeConverter для вашего типа и присоединить его к типу с помощью TypeConverterAttribute. Дополнительные сведения см. в разделе "Определение typeConverter" для замены неявного оператора преобразования.
- Невозможно выполнить разбор XAML во время выполнения методом LoadFromXaml. Хотя это можно сделать безопасным для обрезки путем аннотирования всех типов, которые могут быть загружены во время выполнения, с использованием атрибута
или , это очень подвержено ошибкам и не рекомендуется. - Получение данных навигации с помощью QueryPropertyAttribute не будет работать. Вместо этого следует реализовать IQueryAttributable интерфейс для типов, которые должны принимать параметры запроса. Дополнительные сведения об обработке данных навигации с помощью одного метода см. в этом разделе.
- Свойство
SearchHandler.DisplayMemberNameможет не работать. Вместо этого вам следует предоставить ItemTemplate, чтобы определить внешний вид результатов SearchHandler. Дополнительные сведения см. в разделе "Определение внешнего вида элемента результатов поиска". - Настройка внешнего вида пользовательского интерфейса с расширением разметки XAML
OnPlatformневозможна. Вместо этого следует использовать класс OnPlatform<T>. Дополнительные сведения см. в разделе Настройка внешнего вида пользовательского интерфейса на основе платформы. - Настройка внешнего вида пользовательского интерфейса с расширением разметки XAML
OnIdiomневозможна. Вместо этого следует использовать класс OnIdiom<T>. Дополнительные сведения см. в разделе Настройка внешнего вида пользовательского интерфейса на основе идиом устройства.
Внимание
Интерпретатор Mono несовместим с развертыванием Native AOT, поэтому свойства $(UseInterpreter) и $(MtouchInterpreter) MSBuild не оказывают никакого эффекта при использовании Native AOT. Для получения дополнительной информации об интерпретаторе Mono см. интерпретатор Mono на iOS и Mac Catalyst.
Дополнительные сведения о предупреждениях об обрезке см. в разделе Введение в предупреждения об обрезке. Дополнительные сведения о предупреждениях AOT см. в статье "Введение в предупреждения AOT".
Адаптация приложения к развертыванию Native AOT
Используйте следующий контрольный список, чтобы помочь вам адаптировать приложение к требованиям к развертыванию Native AOT:
- Убедитесь, что весь XAML скомпилирован:
- Удалите все случаи использования
[XamlCompilation(XamlCompilationOptions.Skip)]. - Удалите все
<?xaml-comp compile="false" ?>использование.
- Удалите все случаи использования
- Удалите все вызовы метода LoadFromXaml.
- Убедитесь, что все привязки данных компилируются. Дополнительные сведения см. в разделе "Скомпилированные привязки".
- Убедитесь, что все привязки данных XAML аннотированы с
x:DataType. - Убедитесь, что все привязки данных в коде заменяют все строковые привязки привязками на основе лямбда-выражений.
- Убедитесь, что все привязки данных XAML аннотированы с
- Замените всё использование расширения разметки XAML
OnPlatformреализацией, которая использует класс OnPlatform<T>. Дополнительные сведения см. в разделе Настройка внешнего вида пользовательского интерфейса на основе платформы. - Замените всё использование расширения разметки XAML
OnIdiomреализацией, которая использует класс OnIdiom<T>. Дополнительные сведения см. в разделе Настройка внешнего вида пользовательского интерфейса на основе идиом устройства. - Замените все использования
[QueryProperty(...)]на реализацию интерфейсаIQueryAttributable. Дополнительные сведения об обработке данных навигации с помощью одного метода см. в этом разделе. - Замените все
SearchHandler.DisplayMemberNameиспользование параметром ItemTemplate. Дополнительные сведения см. в разделе "Определение внешнего вида элемента результатов поиска". - Замените все неявные операторы преобразования для типов, используемых в XAML, на TypeConverter, и прикрепите его к своему типу, используя TypeConverterAttribute. Дополнительные сведения см. в разделе "Определение typeConverter" для замены неявного оператора преобразования.
- При преобразовании из типа
Aв типBбудет использоваться методConvertToв преобразователе типов, связанном сA, или методConvertFromв преобразователе типов, связанном сB. - Если исходный и целевой типы имеют связанный преобразователь типов, можно использовать любой из них.
- При преобразовании из типа
- Скомпилируйте все регулярные выражения с помощью генераторов источников. Дополнительные сведения см. в разделе генераторов источников регулярных выражений .NET.
- Убедитесь, что сериализация и десериализация JSON используют созданный на основе исходного контекст. Дополнительные сведения см. в разделе Минимальные API и полезные нагрузки JSON.
- Проверьте и исправьте все предупреждения обрезки или AOT. Дополнительные сведения см. в разделе "Введение в предупреждения об обрезке" и "Введение в предупреждения AOT".
- Тщательно протестируйте приложение.
Встроенная поддержка диагностики AOT в iOS и Mac Catalyst
AOT и Mono в режиме Native имеют общее подмножество возможностей диагностики и инструментирования. Благодаря широкому спектру диагностических средств Mono, бывает полезно диагностировать и отлаживать проблемы именно в Mono, а не в Native AOT. Приложения, которые являются легковесными и совместимыми с AOT-компиляцией, не должны иметь различий в поведении, поэтому исследования часто применяются к обеим средам выполнения.
В следующей таблице показана поддержка диагностики с использованием нативного AOT на iOS и Mac Catalyst.
| Функция | полностью поддерживается. | Частично поддерживается | Не поддерживается |
|---|---|---|---|
| Наблюдаемость и телеметрия | Частично поддерживается | ||
| Диагностика во время разработки | Полностью поддерживается | ||
| Собственная отладка | Частично поддерживается | ||
| Профилирование ЦП | Частично поддерживается | ||
| Анализ кучи | Не поддерживаются |
В следующих разделах приведены дополнительные сведения об этой диагностической поддержке.
Наблюдаемость и телеметрия
Трассировка приложений .NET MAUI на мобильных платформах осуществляется с помощью dotnet-dsrouter, который соединяет средства диагностики с приложениями .NET, работающими на iOS и Mac Catalyst, через TCP/IP. Однако нативный AOT в настоящее время несовместим с этим сценарием, так как он не поддерживает компоненты EventPipe/DiagnosticServer, построенные на основе стека TCP/IP. Наблюдаемость по-прежнему достижима явным образом в коде.
Диагностика на этапе разработки
Средства командной строки .NET предоставляют отдельные команды для build и publish.
dotnet build (или Start Debugging (F5) в Visual Studio Code) использует Mono по умолчанию при создании или запуске приложений .NET MAUI iOS или Mac Catalyst. В файле проекта будет создано только dotnet publish собственное приложение AOT, если эта модель развертывания включена в файле проекта.
Не все средства диагностики будут работать беспроблемно с опубликованными нативными AOT приложениями. Однако все приложения, которые являются обрезными и совместимыми с AOT (т. е. теми, которые не создают никаких предупреждений обрезки и AOT во время сборки) не должны иметь различий в поведении между Mono и Native AOT. Поэтому все средства диагностики во время разработки .NET, такие как Горячая перезагрузка, по-прежнему доступны разработчикам во время цикла разработки мобильных приложений.
Совет
Вы должны разрабатывать, отлаживать и тестировать приложение как обычно и публиковать окончательное приложение с помощью Native AOT в качестве одного из последних шагов.
Нативная отладка
При запуске приложения .NET MAUI iOS или Mac Catalyst во время разработки он выполняется в Mono по умолчанию. Однако если развертывание Native AOT включено в файле проекта, то поведение, как ожидается, будет одинаковым между Mono и Native AOT в случае, если приложение не создает предупреждений об удалении и AOT во время сборки. Если приложение соответствует этому требованию, вы можете использовать стандартный модуль управляемой отладки Visual Studio Code для разработки и тестирования.
После публикации собственные приложения AOT являются собственными двоичными файлами, поэтому управляемый отладчик не будет работать над ними. Однако нативный компилятор AOT создает полностью нативные исполняемые файлы, с которыми можно выполнить отладку lldb. Отладка приложения lldb Mac Catalyst проста, так как оно выполняется на той же системе. Однако отладка приложений NativeAOT для iOS требует дополнительных усилий.
Отладка iOS приложений .NET MAUI с использованием нативного AOT
Приложения iOS .NET MAUI, совместимые с Native AOT и которые правильно настроены и опубликованы с помощью этой модели развертывания, можно выполнить отладку следующим образом:
Опубликуйте приложение с использованием таргетинга Native AOT
ios-arm64и обратите внимание на следующую информацию:- Имя приложения (по ссылке ниже).
<app-name> - Идентификатор пакета (на который ссылается ниже
<bundle-identifier>). - Путь к архиву файла .ipa опубликованного приложения, (ссылка приведена ниже
<path-to-ipa>).
- Имя приложения (по ссылке ниже).
Получите идентификатор физического устройства (по ссылке ниже):
<device-identifier>xcrun devicectl list devicesУстановите приложение на физическом устройстве:
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>Запустите приложение на физическом устройстве:
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>Откройте
lldbи подключитесь к вашему физическому устройству:(lldb) device select <device-identifier> (lldb) device process attach -n <app-name>
После успешного выполнения этих действий вы сможете начать отладку нативного приложения AOT .NET MAUI iOS с помощью lldb.
Важность файла символов
По умолчанию символы отладки удаляются из двоичного файла приложения в DSYM-файл . Этот файл используется отладчиками и инструментами для посмертного анализа для отображения сведений о локальных переменных, номерах строк исходного кода и трассировок стека для воссоздания дампов сбоев. Поэтому необходимо сохранить файл символов перед отправкой приложения в App Store.
Профилирование ЦП
Инструменты Xcode можно использовать для сбора примеров ЦП собственного приложения AOT.
Анализ кучи
В настоящее время анализ кучи не поддерживается в Native AOT.