Limitaciones de Xamarin.iOS
Dado que las aplicaciones que usan Xamarin.iOS se compilan en código estático, no es posible usar ninguna función que requiera generación de código en tiempo de ejecución.
Estas son las limitaciones de Xamarin.iOS en comparación con Mono de escritorio:
Compatibilidad con genéricos limitados
A diferencia de Mono/.NET tradicional, el código del iPhone se compila estáticamente con antelación en lugar de compilarse a petición por un compilador JIT.
La tecnología AOT completa de Mono tiene algunas limitaciones con respecto a los genéricos, que se deben a que no todas las creaciones de instancias genéricas posibles se pueden determinar por adelantado en tiempo de compilación. Esto no es un problema para los entornos de ejecución Mono o .NET normales, ya que el código siempre se compila en tiempo de ejecución mediante el compilador Just-In-Time. Pero esto supone un desafío para un compilador estático como Xamarin.iOS.
Algunos de los problemas comunes con los que se encuentran los desarrolladores incluyen:
Las subclases genéricas de NSObjects están limitadas
Actualmente, Xamarin.iOS tiene compatibilidad limitada para crear subclases genéricas de la clase NSObject. Por ejemplo: ninguna compatibilidad con métodos genéricos. A partir de la versión 7.2.1, es posible usar subclases genéricas de NSObjects, como esta:
class Foo<T> : UIView {
[..]
}
Nota:
Aunque sea posible usar subclases genéricas de NSObjects, hay algunas limitaciones. Lea el documento Subclases genéricas de NSObject para obtener más información
Sin generación de código dinámico
Dado que el kernel de iOS impide que una aplicación genere código dinámicamente, Xamarin.iOS no admite ninguna forma de generación de código dinámico. Entre ellas se incluyen las siguientes:
- System.Reflection.Emit no está disponible.
- System.Runtime.Remoting no se admite.
- No se admite la creación dinámica de tipos (como Type.GetType ("MyType`1")), aunque funciona bien buscar tipos existentes, como (Type.GetType ("System.String")).
- Las devoluciones de llamada inversas deben registrarse con el runtime en tiempo de compilación.
System.Reflection.Emit
La falta de System.Reflection. Emit significa que no funcionará ningún tipo de código que dependa de la generación de código en tiempo de ejecución. Esto incluye elementos como:
Dynamic Language Runtime.
Cualquier lenguaje basado en Dynamic Language Runtime.
TransparentProxy de comunicación remota o cualquier otra cosa que hiciera que el runtime generase código dinámicamente.
Importante
No confunda Reflection.Emit con Reflection. Reflection.Emit consiste en generar código dinámicamente y tener ese código JITed y compilado en código nativo. Debido a las limitaciones de iOS (sin compilación JIT), esto no se admite.
Pero toda la API de Reflection funciona bien, incluyendo Type.GetType ("someClass"), la enumeración de métodos, la enumeración de propiedades y la captura de atributos.
Uso de delegados para llamar a funciones nativas
Para llamar a funciones nativas a través de un delegado de C#, la declaración del delegado deberá estar decorada con uno de los atributos siguientes:
- UnmanagedFunctionPointerAttribute (preferido, ya que es multiplataforma y compatible con .NET Standard 1.1+)
- MonoNativeFunctionWrapperAttribute
Si no se proporcionase uno de estos atributos, se producirá un error en tiempo de ejecución como:
System.ExecutionEngineException: Attempting to JIT compile method '(wrapper managed-to-native) YourClass/YourDelegate:wrapper_aot_native(object,intptr,intptr)' while running in aot-only mode.
Devoluciones de llamada inversas
En Mono estándar, es posible pasar instancias de delegado de C# al código no administrado en lugar de un puntero de función. Normalmente, el runtime transformaría esos punteros de función en un pequeño código thunk que permite que el código no administrado vuelva a llamar al código administrado.
En Mono, el compilador Just-In-Time implementa estos puentes. Al usar el compilador por adelantado requerido por el iPhone, hay dos limitaciones importantes en este punto:
- Se deben marcar todos los métodos de devolución de llamada con MonoPInvokeCallbackAttribute
- Los métodos deben ser métodos estáticos. No hay compatibilidad con los métodos de instancia.
Sin comunicación remota
La pila de comunicación remota no está disponible en Xamarin.iOS.
Características deshabilitadas en el runtime
Las siguientes características se deshabilitaron en el runtime de iOS de Mono:
- Generador de perfiles
- Reflection.Emit
- Funcionalidad Reflection.Emit.Save
- Enlaces COM
- Motor JIT
- Comprobador de metadatos (ya que no hay JIT)
Limitaciones de la API de .NET
La API de .NET expuesta es un subconjunto del marco completo, ya que no todo está disponible en iOS. Consulte las Preguntas más frecuentes para obtener una lista de los ensamblados admitidos en este momento.
En concreto, el perfil de API usado por Xamarin.iOS no incluye System.Configuration, por lo que no es posible usar archivos XML externos para configurar el comportamiento del runtime.