Compartir a través de


Implementación nativa de AOT en iOS y Mac Catalyst

La implementación nativa de AOT genera una aplicación de interfaz de usuario de aplicación multiplataforma de .NET (.NET MAUI) en iOS y Mac Catalyst que se ha compilado con antelación (AOT) en código nativo. AOT nativo realiza análisis de programas estáticos, recorte completo de la aplicación, que es agresivo al quitar código al que no se hace referencia estáticamente y a la generación de código de antemano.

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 AOT significa que la aplicación no es compatible con la implementación de AOT nativa y que podría no funcionar correctamente. Por lo tanto, al compilar una aplicación para la implementación de AOT nativa, 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 e 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 nativas de rendimiento 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:

Gráfico que muestra el tamaño del paquete de la aplicación 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 mono y nativa de AOT:

Gráfico que muestra el promedio de tiempo de inicio de la aplicación en Mono y AOT nativo.

En el gráfico anterior se muestra que AOT nativo normalmente tiene hasta 2 veces más rápidos tiempos de inicio en dispositivos iOS y un tiempo de inicio 1,2x más rápido 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:

Gráfico que muestra el promedio de tiempo de compilación de aplicaciones en Mono y AOT nativo.

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 lentas para las aplicaciones universales en comparación con la implementación 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.

Publicación mediante AOT nativo

El modelo de implementación de AOT nativo está habilitado con la $(PublishAot) propiedad build y el dotnet publish comando . 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 $(IsAotCompatible) propiedad truebuild en , para todas las plataformas, se habilitan 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)trueen , para iOS y Mac Catalyst, permite el análisis dinámico del uso de código durante la compilació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 build 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 conmutadores de características, consulte Trimming feature switches (Recorte de conmutadores de características).

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 detectar problemas de recorte o AOT al principio del ciclo de vida de desarrollo.

Limitaciones de AOT nativas

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, 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 las aplicaciones no sean compatibles con AOT. La única manera de asegurarse de que una biblioteca está recortando y que AOT es compatible con publicar la aplicación mediante la implementación nativa de AOT y el dotnet publish comando, y ver si el compilador de AOT nativo genera advertencias 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, no puede analizar estáticamente y, por tanto, no puede compilar la aplicación, genera advertencias de recorte. 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, no puede compilar con antelación, generará una advertencia de AOT.

En la aplicación MAUI de .NET esto significa que:

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:

Compatibilidad nativa 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 compatibles con AOT y recortadas 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 Compatibilidad parcial No compatible
Observabilidad y telemetría Compatibilidad parcial
Diagnósticos en 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 esta compatibilidad con diagnósticos.

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 son recortadas y compatibles con AOT (es decir, las que no producen ninguna advertencia de recorte y AOT en tiempo de compilación) no deben tener diferencias de comportamiento entre Mono y AOT nativo. Por lo tanto, todas las herramientas de diagnóstico en tiempo de desarrollo de .NET, como Recarga activa, 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 directa, 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:

  1. Publique la aplicación con el destino ios-arm64 de 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 .ipa de archivo de la aplicación publicada (al que se hace referencia a continuación como <path-to-ipa>).
  2. Obtenga el identificador de dispositivo físico (al que se hace referencia a continuación como <device-identifier>):

    xcrun devicectl list devices
    
  3. Instale la aplicación en el dispositivo físico:

    xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
    
  4. Inicie la aplicación en el dispositivo físico:

    xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
    
  5. Abra lldb y conéctese al dispositivo físico:

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

Después de completar correctamente estos pasos, podrá iniciar la depuración de la 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, números de línea de origen y para volver a crear seguimientos de pila de volcados de memoria. 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.

Consulte también