Xamarin.iOS の制限事項
Xamarin.iOS を使用するアプリケーションは静的コードにコンパイルされるため、実行時にコード生成を必要とする機能を使用することはできません。
デスクトップ Mono と比較した Xamarin.iOS の制限事項は次のとおりです。
ジェネリックの制限付きサポート
従来の Mono/.NET とは異なり、iPhone のコードは、JIT コンパイラによってオンデマンドでコンパイルされるのではなく、事前に静的にコンパイルされます。
Mono のフル AOT テクノロジにはジェネリックに関するいくつかの制限事項があります。これらは、コンパイル時にすべての可能なジェネリックのインスタンス化を事前に決定できるわけではないために発生します。 コードは常に Just in Time コンパイラを使用して実行時にコンパイルされるため、これは通常の .NET ランタイムまたは Mono ランタイムでは問題ではありません。 ただし、これは Xamarin.iOS のような静的コンパイラにとって課題となります。
開発者が直面する一般的な問題には、次のようなものがあります。
NSObject のジェネリック サブクラスは制限されます
現在、Xamarin.iOS では、ジェネリック メソッドのサポートがないなど、NSObject クラスのジェネリック サブクラスを作成するためのサポートが制限されています。 7.2.1 では、次のような NSObjects のジェネリック サブクラスを使用できます。
class Foo<T> : UIView {
[..]
}
Note
NSObject のジェネリック サブクラスは使用できますが、いくつかの制限事項があります。 詳細については、NSObject のジェネリック サブクラスに関するドキュメントを参照してください
動的コード生成なし
iOS カーネルではアプリケーションがコードを動的に生成できなくなるため、Xamarin.iOS ではどのような形式の動的コード生成もサポートされません。 これには以下が含まれます。
- System.Reflection.Emit は使用できません。
- System.Runtime.Remoting はサポートされません。
- (Type.GetType ("System.String")) の検索は問題なく動作しますが、型の動的な作成はサポートされません (Type.GetType ("MyType'1") はありません)。
- リバース コールバックは、コンパイル時にランタイムに登録する必要があります。
System.Reflection.Emit
System.Reflection の欠如。 [出力] は、ランタイム コードの生成に依存するコードが機能しないことを意味します。 これには次のものが含まれます。
動的言語ランタイム。
動的言語ランタイムの上に構築された任意の言語。
リモート処理の TransparentProxy など、ランタイムで動的にコードを生成するようなものです。
重要
Reflection.Emit とリフレクションを混同しないでください。 Reflection.Emit はコードを動的に生成し、そのコードを JIT 処理し、ネイティブ コードにコンパイルするものです。 iOS の制限 (JIT コンパイルがない) により、これはサポートされていません。
ただし、Type.GetType ("someClass")、メソッドの一覧表示、プロパティの一覧表示、属性と値のフェッチなど、リフレクション API 全体では問題なく動作します。
デリゲートを使用してネイティブ関数を呼び出す
C# デリゲートを介してネイティブ関数を呼び出すには、デリゲートの宣言を次のいずれかの属性で修飾する必要があります。
- UnmanagedFunctionPointerAttribute (クロスプラットフォームであり、.NET Standard 1.1 以降と互換性があるため、推奨)
- MonoNativeFunctionWrapperAttribute
これらの属性のいずれかを指定しないと、次のようなランタイム エラーが発生します。
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.
リバース コールバック
標準 Mono では、関数ポインターの代わりに C# デリゲート インスタンスをアンマネージド コードに渡すことができます。 通常、ランタイムは、これらの関数ポインターを小さなサンクに変換し、アンマネージド コードがマネージド コードにコールバックできるようにします。
Mono では、これらのブリッジは Just-In-Time コンパイラによって実装されます。 iPhone で必要な事前コンパイラを使用する場合、この時点では次の 2 つの重要な制限事項があります。
- MonoPInvokeCallbackAttribute を使用して、すべてのコールバック メソッドにフラグを設定する必要があります
- メソッドは静的メソッドである必要があります。インスタンス メソッドはサポートされません。
リモート処理なし
リモート処理スタックは Xamarin.iOS では使用できません。
ランタイムで無効になる機能
Mono の iOS ランタイムでは、次の機能が無効になっています。
- Profiler
- Reflection.Emit
- Reflection.Emit.Save 機能
- COM バインド
- JIT エンジン
- メタデータ検証ツール (JIT がないため)
.NET API の制限
公開されている .NET API は、完全なフレームワークのサブセットであり、iOS ですべてを使用できるわけではありません。 現在サポートされているアセンブリの一覧については、FAQ を参照してください。
特に、Xamarin.iOS で使用される API プロファイルには System.Configuration が含まれていないため、外部 XML ファイルを使用してランタイムの動作を構成することはできません。