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 AOT genera una aplicación .NET Multi-platform App UI (.NET MAUI) en iOS y Mac Catalyst que se ha compilado por adelantado (AOT) a código nativo. El AOT nativo realiza un análisis estático del programa, un recorte completo de la aplicación —que elimina de forma agresiva el código al que no se hace referencia de forma estática— y la generación de código por adelantado.
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. Esto requerirá que adaptes tus aplicaciones a los requisitos del AOT nativo, lo que significa asegurarte de que sean totalmente compatibles con el recorte y el 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 de AOT. Una sola advertencia de recorte o de AOT significa que la aplicación no es compatible con la implementación de Native AOT y que es posible que no funcione correctamente. Por lo tanto, al compilar una aplicación para su implementación con Native AOT, debes revisar y corregir todas las advertencias de recorte y de 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 no sea posible corregir las advertencias de recorte y de AOT, como cuando se producen en 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.
El siguiente gráfico muestra el tiempo medio de inicio, en un hardware específico, de una aplicación dotnet new maui en iOS y Mac Catalyst con implementaciones Mono y AOT nativo:
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 activan los analizadores de recorte 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
Publica las aplicaciones con frecuencia para detectar problemas de recorte o AOT en una fase temprana del ciclo de vida del desarrollo.
Limitaciones de AOT nativo
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. Tendrás que adaptar tus aplicaciones a los requisitos de AOT nativo, lo que implica garantizar que sean totalmente compatibles con el recorte y AOT, y esto puede suponer 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 propiedad
SearchHandler.DisplayMemberNameno 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, consulte Intérpretes 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)]. - Elimine todo el uso de
<?xaml-comp compile="false" ?>.
- 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.
- Revisa y corrige cualquier advertencia relacionada con trim 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 compatibles con trim y AOT (es decir, aquellas que no generan ninguna advertencia relacionada con trim ni AOT durante la compilación) no deberían presentar diferencias de comportamiento entre Mono y Native AOT. 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 de Mac Catalyst con lldb es sencillo, 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:
Publica tu aplicación con AOT nativo dirigido a
ios-arm64y toma nota de 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>
Una vez completados con éxito estos pasos, podrás empezar a depurar tu aplicación .NET MAUI para iOS con AOT nativo utilizando lldb.
Importancia del archivo de símbolos
De forma predeterminada, los símbolos de depuración se extraen del archivo binario de la aplicación y se guardan en un archivo .dSYM. Este archivo lo utilizan los depuradores y las herramientas de análisis post mortem para mostrar información sobre variables locales y números de línea de código fuente, así como para recrear trazas de pila de los volcados de memoria por fallo. 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, el análisis de montón no es compatible con Native AOT.