Einschränkungen von Xamarin.iOS

Da Anwendungen, die Xamarin.iOS verwenden, in statischen Code kompiliert werden, ist es nicht möglich, Einrichtungen zu verwenden, die zur Laufzeit eine Codegenerierung erfordern.

Dies sind die Xamarin.iOS-Einschränkungen im Vergleich zu Desktop Mono:

Eingeschränkte Generics-Unterstützung

Im Gegensatz zu herkömmlichem Mono/.NET wird Code auf dem iPhone im Voraus statisch kompiliert, anstatt bei Bedarf von einem JIT-Compiler kompiliert zu werden.

Die Vollständige AOT-Technologie von Mono weist einige Einschränkungen in Bezug auf Generics auf. Diese sind darauf zurückzuführen, dass nicht jede mögliche generische Instanziierung zur Kompilierzeit im Voraus bestimmt werden kann. Dies ist kein Problem für reguläre .NET- oder Mono-Runtimes, da der Code zur Laufzeit immer mit dem Just-in-Time-Compiler kompiliert wird. Dies stellt jedoch eine Herausforderung für einen statischen Compiler wie Xamarin.iOS dar.

Zu den häufig auftretenden Problemen, auf die Entwickler stoßen, gehören:

Generische Unterklassen von NSObjects sind eingeschränkt

Xamarin.iOS bietet derzeit eingeschränkte Unterstützung für das Erstellen generischer Unterklassen der NSObject-Klasse, z. B. keine Unterstützung für generische Methoden. Ab 7.2.1 ist die Verwendung generischer Unterklassen von NSObjects wie folgt möglich:

class Foo<T> : UIView {
    [..]
}

Hinweis

Generische Unterklassen von NSObjects sind zwar möglich, es gibt jedoch einige Einschränkungen. Weitere Informationen finden Sie im Dokument Generic subclasses of NSObject (Generische Unterklassen von NSObject ).

Keine dynamische Codegenerierung

Da der iOS-Kernel verhindert, dass eine Anwendung Code dynamisch generiert, unterstützt Xamarin.iOS keine Form der dynamischen Codegenerierung. Dazu zählen unter anderem folgende Einstellungen:

  • System.Reflection.Emit ist nicht verfügbar.
  • Keine Unterstützung für System.Runtime.Remoting.
  • Es wird keine dynamische Erstellung von Typen (kein Type.GetType ("MyType'1")) unterstützt, obwohl die Suche nach vorhandenen Typen (z.B. Type.GetType ("System.String") gut funktioniert.
  • Reverserückrufe müssen zur Kompilierzeit bei der Laufzeit registriert werden.

System.Reflection.Emit

Das Fehlen von System.Reflection. Ausgeben bedeutet, dass kein Code funktioniert, der von der Laufzeitcodegenerierung abhängt. Dazu zählen etwa:

  • Die Dynamic Language Runtime.

  • Alle Sprachen, die auf der Dynamic Language Runtime aufbauen.

  • TransparentProxy von Remoting oder andere Objekte, die dazu führen würden, dass die Laufzeit Code dynamisch generiert.

    Wichtig

    Verwechseln Sie Reflection.Emit nicht mit Reflektion. Bei Reflection.Emit geht es darum, Code dynamisch zu generieren und diesen Code jited und in nativen Code zu kompilieren. Aufgrund der Einschränkungen unter iOS (keine JIT-Kompilierung) wird dies nicht unterstützt.

Die gesamte Reflektions-API, einschließlich Type.GetType ("someClass"), das Auflisten von Methoden, das Auflisten von Eigenschaften, das Abrufen von Attributen und Werten, funktioniert jedoch einwandfrei.

Verwenden von Delegaten zum Aufrufen von nativen Funktionen

Um eine native Funktion über einen C#-Delegaten aufzurufen, muss die Deklaration des Delegaten mit einem der folgenden Attribute versehen werden:

Wenn Eines dieser Attribute nicht angegeben wird, führt dies zu einem Laufzeitfehler, z. B.:

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.

Umgekehrte Rückrufe

In Mono-Standard ist es möglich, C#-Delegatinstanzen anstelle eines Funktionszeigers an nicht verwalteten Code zu übergeben. Die Runtime würde diese Funktionszeiger in der Regel in einen kleinen Thunk transformieren, der es nicht verwaltetem Code ermöglicht, in verwaltetem Code zurückzurufen.

In Mono werden diese Brücken vom Just-in-Time-Compiler implementiert. Wenn Sie den für die iPhone erforderlichen Compiler im Voraus verwenden, gibt es an dieser Stelle zwei wichtige Einschränkungen:

  • Sie müssen alle Rückrufmethoden mit monoPInvokeCallbackAttribute kennzeichnen.
  • Die Methoden müssen statische Methoden sein, es gibt keine Unterstützung für Instanzmethoden.

Kein Remoting

Der Remotingstapel ist unter Xamarin.iOS nicht verfügbar.

Deaktivierte Runtimefeatures

Die folgenden Features wurden in der iOS-Runtime von Mono deaktiviert:

  • Profiler
  • Reflection.Emit
  • Reflection.Emit.Save-Funktionalität
  • COM-Bindungen
  • Die JIT-Engine
  • Metadatenüberprüfung (da kein JIT vorhanden ist)

Einschränkungen der .NET-API

Die verfügbar gemachte .NET-API ist eine Teilmenge des vollständigen Frameworks, da nicht alles in iOS verfügbar ist. Eine Liste der derzeit unterstützten Assemblys finden Sie in den häufig gestellten Fragen.

Insbesondere enthält das von Xamarin.iOS verwendete API-Profil nicht System.Configuration, sodass es nicht möglich ist, externe XML-Dateien zum Konfigurieren des Verhaltens der Laufzeit zu verwenden.