Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La implementación nativa de AOT genera una aplicación de interfaz de usuario multiplataforma de .NET (.NET MAUI) en iOS y Mac Catalyst que ha sido compilada por adelantado (AOT) a código nativo. El AOT nativo realiza un análisis estático de programas, un podado completo de la aplicación, que es agresivo en la eliminación de código no referenciado estáticamente, y la generación de código anticipada.
La publicación e implementación de una aplicación AOT nativa genera las siguientes ventajas:
- Tamaño reducido del paquete de la aplicación.
- Tiempo de inicio más rápido.
- Tiempo de compilación más rápido.
AOT nativo introducirá limitaciones en el uso de determinados aspectos del entorno de ejecución de .NET y solo debe usarse en escenarios en los que el tamaño y el rendimiento de la aplicación sean importantes. Necesitará adaptar las aplicaciones a los requisitos nativos de AOT, lo que significa asegurarse de que son totalmente recortados y compatibles con AOT. Para obtener más información sobre las limitaciones de AOT nativas, consulte Limitaciones de AOT nativas.
Cuando la implementación de AOT nativa está habilitada, el sistema de compilación analiza el código y todas sus dependencias para comprobar si es adecuado para el recorte completo y la compilación AOT. Si se detectan incompatibilidades, se generan advertencias de recorte y AOT. Una única advertencia de recorte o de AOT significa que la aplicación no es compatible con la implementación nativa de AOT y que podría no funcionar correctamente. Por lo tanto, al compilar una aplicación para la implementación nativa de AOT, debe revisar y corregir todas las advertencias de recorte y AOT. Si no se hace esto, se pueden producir excepciones en tiempo de ejecución, ya que se podría haber quitado el código necesario. Si suprime las advertencias, la aplicación implementada con AOT debe probarse exhaustivamente para comprobar que la funcionalidad no ha cambiado de la aplicación no implementada. Para obtener más información, vea Introducción a las advertencias de recorte y Introducción a las advertencias de AOT.
Nota:
Puede haber casos en los que la corrección del recorte y las advertencias de AOT no son posibles, como cuando se producen para bibliotecas de terceros. En tales casos, las bibliotecas de terceros deberán actualizarse para que sean totalmente compatibles.
Ventajas de rendimiento nativas de AOT
La publicación e implementación de una aplicación AOT nativa genera una aplicación que normalmente es de hasta 2,5x más pequeña y una aplicación que se inicia normalmente hasta 2 veces más rápido. Sin embargo, las ventajas exactas de rendimiento dependen de varios factores que incluyen la plataforma que se usa, el dispositivo en el que se ejecuta la aplicación y la propia aplicación.
Importante
En los gráficos siguientes se muestran las ventajas de rendimiento típicas de la implementación nativa de AOT para una dotnet new maui aplicación en iOS y Mac Catalyst. Sin embargo, los datos exactos dependen del hardware y pueden cambiar en futuras versiones.
En el gráfico siguiente se muestra el tamaño del paquete de la aplicación para una dotnet new maui aplicación en iOS y Mac Catalyst en diferentes modelos de implementación:
En el gráfico anterior se muestra que, normalmente, AOT nativo genera más de 2 veces aplicaciones más pequeñas para iOS y Mac Catalyst en comparación con el modelo de implementación predeterminado.
En el gráfico siguiente se muestra el tiempo medio de inicio, en hardware específico, para una dotnet new maui aplicación en iOS y Mac Catalyst en la implementación de Mono y AOT Nativa:
En el gráfico anterior se muestra que la compilación AOT nativa típicamente tiene tiempos de inicio hasta 2 veces más rápidos en dispositivos iOS y tiempos de inicio 1,2 veces más rápidos en Mac Catalyst, en comparación con la implementación Mono.
En el gráfico siguiente se muestra el tiempo medio de compilación, en hardware específico, para una dotnet new maui aplicación en iOS y Mac Catalyst en diferentes modelos de implementación:
En el gráfico anterior se muestra que, normalmente, AOT nativo tiene hasta 2,8 veces más rápidos tiempos de compilación en dispositivos iOS en comparación con el modelo de implementación predeterminado. Para Mac Catalyst, los tiempos de compilación son comparables para las aplicaciones RID únicas arm64, pero son ligeramente más lentos para las aplicaciones universales en comparación con el despliegue Mono.
Importante
En muchos escenarios, AOT nativo producirá aplicaciones más pequeñas y rápidas. Sin embargo, en algunos escenarios es posible que AOT nativo no genere aplicaciones más pequeñas y más rápidas. Por lo tanto, es importante probar y generar perfiles de la aplicación para determinar el resultado de habilitar la implementación nativa de AOT.
Publicar con AOT nativo
El modelo de implementación de AOT nativo está habilitado con la propiedad de compilación $(PublishAot) y el comando dotnet publish. En el ejemplo siguiente se muestra cómo modificar un archivo de proyecto para habilitar la implementación nativa de AOT en iOS y 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>
Al establecer la propiedad de compilación $(IsAotCompatible) en true, para todas las plataformas, se habilitan los analizadores de optimización y AOT. Estos analizadores le ayudan a identificar el código que no es compatible con el recorte o AOT.
Establecer condicionalmente $(PublishAot) como true, para iOS y Mac Catalyst, permite el análisis dinámico de uso de código durante la construcción y la compilación AOT nativa durante la publicación. El análisis de AOT nativo incluye todo el código de la aplicación y todas las bibliotecas de las que depende la aplicación.
Advertencia
La $(PublishAot) propiedad de compilación no debe estar condicionada por la configuración de compilación. Esto se debe a que los modificadores de características de recorte están habilitados o deshabilitados en función del valor de la $(PublishAot) propiedad de compilación, y las mismas características deben habilitarse o deshabilitarse en todas las configuraciones de compilación para que el código se comporte de forma idéntica. Para obtener más información sobre el recorte de interruptores de funciones, consulte Recorte de interruptores de funciones.
La única manera de comprobar que una aplicación AOT nativa funciona correctamente es publicarla mediante dotnet publish y comprobar que no hay advertencias de recorte o AOT generadas por el código y sus dependencias. En concreto, dotnet build -t:Publish no es equivalente a dotnet publish.
Use el siguiente dotnet publish comando para publicar la aplicación en iOS y Mac Catalyst mediante la implementación nativa de 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
Sugerencia
Publique aplicaciones con frecuencia para identificar problemas de recorte o AOT al principio del ciclo de vida de desarrollo.
Limitaciones de la compilación AOT nativa
AOT nativo introducirá limitaciones en el uso de determinados aspectos del entorno de ejecución de .NET y solo debe usarse en escenarios en los que el tamaño y el rendimiento de la aplicación sean importantes. Requerirá que adapte sus aplicaciones a los requisitos nativos de AOT, lo cual significa asegurarse de que sean totalmente recortables y compatibles con AOT, y esto puede requerir mucho trabajo. Además de las limitaciones de .NET de la implementación de AOT nativa, la implementación de AOT nativa para .NET MAUI tiene limitaciones adicionales.
Es posible que las bibliotecas de terceros de tus aplicaciones no sean compatibles con AOT. La única manera de asegurarse de que una biblioteca sea compatible con el recorte y AOT es desplegar la aplicación utilizando la implementación nativa de AOT junto con el comando dotnet publish, y verificar si el compilador de AOT nativo genera alguna advertencia para la biblioteca. Para obtener información sobre cómo hacer que sus propias bibliotecas sean compatibles con AOT, consulte Cómo hacer que las bibliotecas sean compatibles con AOT nativos.
Reflexión y código dinámico
La implementación de AOT nativa limita el uso de reflexión en el código y sus dependencias, y puede ser necesario usar anotaciones para ayudar al compilador de AOT nativo a comprender los patrones de reflexión. Cuando el compilador encuentra un patrón de reflexión que no puede analizar estáticamente y, por tanto, no puede compilar la aplicación, genera advertencias de reducción. AOT nativo también le impide usar código dinámico en la aplicación. Por ejemplo, la compilación System.Linq.Expressions no funcionará según lo previsto y no es posible cargar y ejecutar ensamblados en tiempo de ejecución. Cuando el compilador encuentra un patrón dinámico que no puede compilar por adelantado, emitirá una advertencia de AOT.
En la aplicación MAUI de .NET esto significa que:
- Todo XAML debe estar compilado con antelación. Por lo tanto, asegúrate de no haber deshabilitado la compilación XAML y de que se compilen todas las vinculaciones. Para obtener más información, consulta Compilación XAML y Vinculaciones compiladas.
- Todas las expresiones de enlace deben utilizar enlaces compilados en lugar de una cadena establecida como ruta de enlace. Para obtener más información, consulta Enlaces compilados.
- Es posible que no se llame a los operadores de conversión implícitos al asignar un valor de un tipo incompatible a una propiedad en XAML o cuando dos propiedades de tipos diferentes usan un enlace de datos. En su lugar, debe definir un TypeConverter para el tipo y adjuntarlo a este mediante TypeConverterAttribute. Para obtener más información, vea Definir un TypeConverter para reemplazar un operador de conversión implícito.
- No es posible analizar XAML en tiempo de ejecución con el LoadFromXaml método . Aunque se puede garantizar la seguridad mediante la anotación de todos los tipos que se pueden cargar en tiempo de ejecución con los atributos
DynamicallyAccessedMembersoDynamicDependency, es una práctica muy propensa a errores y no se recomienda. - La recepción de datos de navegación mediante el QueryPropertyAttribute no funcionará. En su lugar, debe implementar la interfaz IQueryAttributable en las clases que necesitan aceptar parámetros de consulta. Para obtener más información, vea Procesamiento de datos de navegación mediante un único método.
- Es posible que la
SearchHandler.DisplayMemberNamepropiedad no funcione. En su lugar, debes proporcionar un ItemTemplate para definir la apariencia de los resultados SearchHandler. Para obtener más información, vea Definir la apariencia del elemento de resultados de búsqueda. - No es posible personalizar la apariencia de la interfaz de usuario con la extensión de marcado XAML
OnPlatform. En su lugar, debería utilizar la clase OnPlatform<T>. Para obtener más información, consulte Personalizar la apariencia de la interfaz de usuario en función de la plataforma. - No es posible personalizar la apariencia de la interfaz de usuario con la extensión de marcado XAML
OnIdiom. En su lugar, debería utilizar la clase OnIdiom<T>. Para obtener más información, consulte Personalizar la apariencia de la interfaz de usuario en función de la expresión del dispositivo.
Importante
El intérprete mono no es compatible con la implementación de AOT nativa y, por tanto, las $(UseInterpreter) propiedades y $(MtouchInterpreter) de MSBuild no tienen ningún efecto al usar AOT nativo. Para obtener más información sobre el intérprete mono, consulte Intérprete mono en iOS y Mac Catalyst.
Para obtener más información sobre las advertencias de recorte, consulte Introducción a las advertencias de recorte. Para obtener más información sobre las advertencias de AOT, vea Introducción a las advertencias de AOT.
Adaptación de una aplicación a la implementación de AOT nativa
Use la siguiente lista de comprobación para ayudarle a adaptar la aplicación a los requisitos de implementación de AOT nativos:
- Asegúrese de que todo XAML está compilado:
- Elimine todo el uso de
[XamlCompilation(XamlCompilationOptions.Skip)]. - Quite todo el
<?xaml-comp compile="false" ?>uso.
- Elimine todo el uso de
- Quite todas las llamadas al LoadFromXaml método .
- Asegúrese de que se compilan todos los enlaces de datos. Para obtener más información, consulta Enlaces compilados.
- Asegúrese de que todos los enlaces de datos XAML se anotan con
x:DataType. - Asegúrese de que todos los enlaces de datos de código reemplazan todos los enlaces basados en cadenas por enlaces basados en lambda.
- Asegúrese de que todos los enlaces de datos XAML se anotan con
- Reemplace todo uso de la extensión de marcado XAML
OnPlatformpor una implementación que utilice la clase OnPlatform<T>. Para obtener más información, consulte Personalizar la apariencia de la interfaz de usuario en función de la plataforma. - Reemplace todo uso de la extensión de marcado XAML
OnIdiompor una implementación que utilice la clase OnIdiom<T>. Para obtener más información, consulte Personalizar la apariencia de la interfaz de usuario en función de la expresión del dispositivo. - Reemplaza todo el uso de
[QueryProperty(...)]por una implementación de la interfazIQueryAttributable. Para obtener más información, vea Procesamiento de datos de navegación mediante un único método. - Reemplaza todos los usos de
SearchHandler.DisplayMemberNamecon un ItemTemplate. Para obtener más información, vea Definir la apariencia del elemento de resultados de búsqueda. - Reemplace todos los operadores de conversión implícitos para los tipos usados en XAML por un TypeConvertery lo adjunte al tipo mediante TypeConverterAttribute. Para obtener más información, vea Definir un TypeConverter para reemplazar un operador de conversión implícito.
- Al convertir de tipo
Aa tipoB, se usará el métodoConvertToen un convertidor de tipos asociado aAo se usará el métodoConvertFromen un convertidor de tipos asociado aB. - Cuando los tipos de origen y destino tienen un convertidor de tipos asociado, se puede usar cualquiera de ellos.
- Al convertir de tipo
- Compile todas las expresiones regulares mediante generadores de origen. Para más información, consulte Generadores de código fuente de expresiones regulares de .NET.
- Asegúrese de que la serialización y la deserialización JSON use un contexto generado por la fuente. Para más información, consulte Minimal APIs y cargas JSON.
- Revise y corrija las advertencias de recorte o AOT. Para obtener más información, vea Introducción a las advertencias de recorte y Introducción a las advertencias de AOT.
- Pruebe exhaustivamente la aplicación.
Soporte nativo de diagnóstico de AOT en iOS y Mac Catalyst
AOT nativo y Mono comparten un subconjunto de funcionalidades de diagnóstico e instrumentación. Debido a la gama de herramientas de diagnóstico de Mono, puede ser beneficioso diagnosticar y depurar problemas dentro de Mono en lugar de AOT nativo. Las aplicaciones que son recortadas y compatibles con AOT no deben tener diferencias de comportamiento, por lo que las investigaciones a menudo se aplican a ambos entornos de ejecución.
En la tabla siguiente se muestra la compatibilidad de diagnóstico con AOT nativo en iOS y Mac Catalyst:
| Característica | Totalmente compatible | Parcialmente soportado | No compatible |
|---|---|---|---|
| Observabilidad y telemetría | Compatibilidad parcial | ||
| Diagnósticos durante el tiempo de desarrollo | Compatibilidad total | ||
| Depuración nativa | Compatibilidad parcial | ||
| Generación de perfiles de CPU | Compatibilidad parcial | ||
| Análisis por montón | No compatible |
En las secciones siguientes se proporciona información adicional sobre este soporte de diagnóstico.
Observabilidad y telemetría
El seguimiento de aplicaciones .NET MAUI en plataformas móviles está habilitado a través de dotnet-dsrouter que conecta herramientas de diagnóstico con aplicaciones .NET que se ejecutan en iOS y Mac Catalyst, a través de TCP/IP. Sin embargo, AOT nativo no es compatible actualmente con este escenario, ya que no admite componentes EventPipe/DiagnosticServer creados con la pila TCP/IP. La observabilidad sigue siendo factible explícitamente en el código.
Diagnósticos en tiempo de desarrollo
Las herramientas de la CLI de .NET proporcionan comandos independientes para build y publish.
dotnet build (o Start Debugging (F5) en Visual Studio Code), usa Mono de forma predeterminada al compilar o iniciar aplicaciones .NET MAUI iOS o Mac Catalyst. Solo dotnet publish creará una aplicación AOT nativa, si este modelo de implementación está habilitado en el archivo del proyecto.
No todas las herramientas de diagnóstico funcionarán sin problemas con las aplicaciones AOT nativas publicadas. Sin embargo, todas las aplicaciones que están optimizadas y son compatibles con AOT (es decir, aquellas que no producen ninguna advertencia de optimización y AOT en tiempo de compilación) no deberían presentar diferencias de comportamiento entre Mono y AOT nativas. Por lo tanto, todas las herramientas de diagnóstico en tiempo de desarrollo de .NET, como Recarga en caliente, siguen estando disponibles para los desarrolladores durante el ciclo de desarrollo de aplicaciones móviles.
Sugerencia
Debe desarrollar, depurar y probar la aplicación como de costumbre y publicar la aplicación final con AOT nativo como uno de los últimos pasos.
Depuración nativa
Al ejecutar la aplicación .NET MAUI iOS o Mac Catalyst durante el desarrollo, se ejecuta en Mono de forma predeterminada. Sin embargo, si la implementación de AOT nativa está habilitada en el archivo del proyecto, se espera que el comportamiento sea el mismo entre Mono y AOT nativo cuando la aplicación no genere ninguna advertencia de recorte y AOT en tiempo de compilación. Siempre que la aplicación cumpla este requisito, puede usar el motor de depuración administrado estándar de Visual Studio Code para desarrollo y pruebas,
Después de la publicación, las aplicaciones AOT nativas son archivos binarios nativos verdaderos, por lo que el depurador administrado no funcionará en ellos. Sin embargo, el compilador AOT nativo genera archivos ejecutables totalmente nativos que puede depurar con lldb. Depurar una aplicación Mac Catalyst con lldb es sencilla, ya que se ejecuta en el mismo sistema. Sin embargo, la depuración de aplicaciones iOS de NativeAOT requiere un esfuerzo adicional.
Depuración de aplicaciones iOS de .NET MAUI con AOT nativo
Las aplicaciones de iOS de .NET MAUI que son compatibles con AOT nativo y que están configuradas y publicadas correctamente con este modelo de implementación, se pueden depurar de la siguiente manera:
Publique la aplicación con el destino
ios-arm64de AOT nativo y anote la siguiente información:- Nombre de la aplicación (al que se hace referencia a continuación como
<app-name>). - Identificador de agrupación (al que se hace referencia a continuación como
<bundle-identifier>). - Ruta de acceso al archivo de la aplicación publicada .ipa (referenciado a continuación como
<path-to-ipa>).
- Nombre de la aplicación (al que se hace referencia a continuación como
Obtenga el identificador de dispositivo físico (al que se hace referencia a continuación como
<device-identifier>):xcrun devicectl list devicesInstale la aplicación en el dispositivo físico:
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>Inicie la aplicación en el dispositivo físico:
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>Abra
lldby conéctese al dispositivo físico:(lldb) device select <device-identifier> (lldb) device process attach -n <app-name>
Después de completar exitosamente estos pasos, puede comenzar a depurar su aplicación nativa AOT .NET MAUI iOS con lldb.
Importancia del archivo de símbolos
De forma predeterminada, los símbolos de depuración se quitan del archivo binario de la aplicación en un archivo .dSYM . Los depuradores y las herramientas de análisis post mortem usan este archivo para mostrar información sobre variables locales y números de línea de origen, y reconstruir trazas de pila de volcados de fallos. Por lo tanto, es esencial conservar el archivo de símbolos antes de enviar la aplicación a App Store.
Generación de perfiles de CPU
Xcode Instruments se puede usar para recopilar ejemplos de CPU de una aplicación AOT nativa.
Análisis del montón
Actualmente no se admite el análisis del montón con AOT nativo.