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 la 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 limitada con genéricos
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 Full AOT de Mono tiene algunas limitaciones con respecto a los genéricos, que se deben a que no todas las 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 normales de .NET o Mono, 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 son:
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, sin 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 las subclases genéricas de NSObjects son posibles, 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
Puesto que el kernel de iOS impide que una aplicación genere código dinámicamente, Xamarin.iOS no admite ninguna forma de generación dinámica de código. Entre ellas se incluyen las siguientes:
- System.Reflection.Emit no está disponible.
- No se admite System.Runtime.Remoting.
- No se admite la creación dinámica de tipos (ningún Type.GetType ("MyType'1")), aunque la búsqueda de tipos existentes (Type.GetType ("System.String") por ejemplo, funciona correctamente).
- Las devoluciones de llamada inversas se deben registrar con el tiempo de ejecución en tiempo de compilación.
System.Reflection.Emit
Falta System.Reflection. Emitir significa que no funcionará ningún código que dependa de la generación de código en tiempo de ejecución. Esto incluye elementos como:
The Dynamic Language Runtime.
Cualquier lenguaje basado en Dynamic Language Runtime.
TransparentProxy de la comunicación remota o cualquier otra cosa que haría que el tiempo de ejecución generara código dinámicamente.
Importante
No confunda Reflection.Emit conReflection. Reflection.Emit trata de generar código dinámicamente y hacer que ese código se jited y se compile en código nativo. Debido a las limitaciones de iOS (sin compilación JIT), esto no se admite.
Pero toda la API de reflexión, incluido Type.GetType ("someClass"), enumerar métodos, enumerar propiedades, capturar atributos y valores funciona correctamente.
Usar delegados para llamar a Funciones nativas
Para llamar a una función nativa a través de un delegado de C#, la declaración del delegado debe decorarse con uno de los atributos siguientes:
- UnmanagedFunctionPointerAttribute (preferido, ya que es multiplataforma y compatible con .NET Standard 1.1+)
- MonoNativeFunctionWrapperAttribute
Si no se proporciona uno de estos atributos, se producirá un error en tiempo de ejecución como el siguiente:
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# a código no administrado en lugar de un puntero de función. El tiempo de ejecución normalmente 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. Cuando se usa el compilador ahead-of-time requerido por el iPhone hay dos limitaciones importantes en este momento:
- Debe 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 tiempo de ejecución
Las siguientes características se han deshabilitado en el entorno de ejecución de iOS de Mono:
- Generador de perfiles
- Reflection.Emit
- Funcionalidad Reflection.Emit.Save
- Enlaces COM
- El motor JIT
- Comprobador de metadatos (puesto 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 actualmente.
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 tiempo de ejecución.