Limitations de Xamarin.iOS
Étant donné que les applications utilisant Xamarin.iOS sont compilées en code statique, il n’est pas possible d’utiliser des installations qui nécessitent la génération de code au moment de l’exécution.
Voici les limitations de Xamarin.iOS par rapport au mono de bureau :
Prise en charge limitée des génériques
Contrairement à Mono/.NET traditionnel, le code sur l’iPhone est compilé de manière statique à l’avance au lieu d’être compilé à la demande par un compilateur JIT.
La technologie Full AOT de Mono présente quelques limitations en ce qui concerne les génériques, car toutes les instanciations génériques possibles ne peuvent pas être déterminées à l’avance au moment de la compilation. Ce n’est pas un problème pour les runtimes .NET ou Mono standard, car le code est toujours compilé au moment de l’exécution à l’aide du compilateur juste-à-temps. Mais cela pose un défi pour un compilateur statique comme Xamarin.iOS.
Voici quelques-uns des problèmes courants rencontrés par les développeurs :
Les sous-classes génériques de NSObjects sont limitées
Xamarin.iOS offre actuellement une prise en charge limitée de la création de sous-classes génériques de la classe NSObject, par exemple l’absence de prise en charge des méthodes génériques. À partir de la version 7.2.1, l’utilisation de sous-classes génériques de NSObjects est possible, comme celle-ci :
class Foo<T> : UIView {
[..]
}
Notes
Bien que les sous-classes génériques de NSObjects soient possibles, il existe quelques limitations. Pour plus d’informations, consultez les sous-classes génériques du document NSObject
Aucune génération de code dynamique
Étant donné que le noyau iOS empêche une application de générer du code dynamiquement, Xamarin.iOS ne prend en charge aucune forme de génération de code dynamique. Il s’agit notamment des paramètres suivants :
- System.Reflection.Emit n’est pas disponible.
- Aucune prise en charge de System.Runtime.Remoting.
- Aucune prise en charge de la création de types de manière dynamique (aucun Type.GetType (« MyType'1 »)), bien que la recherche de types existants (Type.GetType (« System.String ») par exemple fonctionne très bien).
- Les rappels inversés doivent être inscrits auprès du runtime au moment de la compilation.
System.Reflection.Emit
L’absence de System.Reflection. L’émission signifie qu’aucun code qui dépend de la génération de code d’exécution ne fonctionnera. Cela inclut des éléments tels que :
The Dynamic Language Runtime.
Tous les langages créés par-dessus le Dynamic Language Runtime.
TransparentProxy de Remoting ou tout autre élément qui entraînerait la génération dynamique du code par le runtime.
Important
Ne confondez pas Reflection.Emit avec Reflection. Reflection.Emit a pour objet de générer du code de manière dynamique et d’avoir ce code jited et compilé en code natif. En raison des limitations sur iOS (aucune compilation JIT), cela n’est pas pris en charge.
Mais l’ENSEMBLE de l’API Reflection, y compris Type.GetType (« someClass »), les méthodes de référencement, les propriétés de liste, l’extraction des attributs et des valeurs fonctionne parfaitement.
Utilisation de délégués pour appeler des fonctions natives
Pour appeler une fonction native via un délégué C#, la déclaration du délégué doit être décorée avec l’un des attributs suivants :
- UnmanagedFunctionPointerAttribute (préféré, car il est multiplateforme et compatible avec .NET Standard 1.1+)
- MonoNativeFunctionWrapperAttribute
Si vous ne fournissez pas l’un de ces attributs, une erreur d’exécution telle que :
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.
Rappels inversés
Dans mono standard, il est possible de passer des instances de délégué C# à du code non managé au lieu d’un pointeur de fonction. Le runtime transforme généralement ces pointeurs de fonction en un petit thunk qui permet au code non managé de rappeler dans du code managé.
Dans Mono, ces ponts sont implémentés par le compilateur juste-à-temps. Lors de l’utilisation du compilateur d’avance requis par l’iPhone, il existe deux limitations importantes à ce stade :
- Vous devez marquer toutes vos méthodes de rappel avec l’attribut MonoPInvokeCallbackAttribute
- Les méthodes doivent être statiques. Il n’existe aucune prise en charge des méthodes instance.
Aucune communication à distance
La pile de communication à distance n’est pas disponible sur Xamarin.iOS.
Fonctionnalités d’exécution désactivées
Les fonctionnalités suivantes ont été désactivées dans le runtime iOS de Mono :
- Profileur
- Reflection.Emit
- Fonctionnalité Reflection.Emit.Save
- Liaisons COM
- Moteur JIT
- Vérificateur de métadonnées (puisqu’il n’y a pas de JIT)
Limitations de l’API .NET
L’API .NET exposée est un sous-ensemble de l’infrastructure complète, car tout n’est pas disponible dans iOS. Consultez la FAQ pour obtenir la liste des assemblys actuellement pris en charge.
En particulier, le profil d’API utilisé par Xamarin.iOS n’inclut pas System.Configuration. Il n’est donc pas possible d’utiliser des fichiers XML externes pour configurer le comportement du runtime.