Xamarin.iOS 的限制
由於使用 Xamarin.iOS 的應用程式會編譯為靜態程式代碼,因此無法在運行時間使用任何需要產生程式代碼的設施。
這些是與桌面Mono相比的 Xamarin.iOS 限制:
有限的泛型支援
不同於傳統的Mono/.NET,i 電話 上的程式代碼會事先靜態編譯,而不是由 JIT 編譯程式視需要編譯。
Mono 的完整 AOT 技術在泛型方面有一些限制,因此會造成這些限制,因為並非所有可能的泛型具現化都可以在編譯階段預先決定。 這不適用於一般 .NET 或Mono運行時間,因為程式代碼一律會在運行時間使用 Just in Time 編譯程式進行編譯。 但這對像 Xamarin.iOS 這樣的靜態編譯程式構成挑戰。
開發人員遇到的一些常見問題包括:
NSObjects 的泛型子類別有限
Xamarin.iOS 目前對建立 NSObject 類別的泛型子類別的支援有限,例如不支援泛型方法。 從 7.2.1 起,可以使用 NSObjects 的泛型子類別,如下所示:
class Foo<T> : UIView {
[..]
}
注意
雖然 NSObjects 的泛型子類別是可能的,但有一些限制。 如需詳細資訊,請閱讀 NSObject 檔的泛型子類別
無動態程式代碼產生
由於 iOS 核心會防止應用程式動態產生程式碼,因此 Xamarin.iOS 不支援任何形式的動態程式代碼產生。 包括:
- 系統。反思。無法發出。
- 不支援 System.Runtime.Remoting。
- 不支持動態建立類型(沒有 Type.GetType (“MyType'1”)),但查閱現有的類型(例如 Type.GetType (“System.String”) 運作正常)。
- 反向回呼必須在編譯時期向運行時間註冊。
System.Reflection.Emit
缺乏系統。反思。 發出 表示任何相依於運行時間程式代碼產生的程式代碼將無法運作。 這包括下列專案:
動態語言執行平臺。
建置在動態語言執行平臺之上的任何語言。
遠端的 TransparentProxy 或其他任何會導致運行時間動態產生程式代碼的專案。
重要
請勿混淆 反思。使用 反思 ion 發出。 反思。發出是關於以動態方式產生程序代碼,並讓該程式代碼 JITed 編譯成機器碼。 由於 iOS 的限制(沒有 JIT 編譯),因此不受支援。
但整個 反思 API,包括 Type.GetType (“someClass”),列出方法、列出屬性、擷取屬性和值的運作正常。
使用委派呼叫 Native Functions
若要透過 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# 委派實例傳遞至 Unmanaged 程式代碼,而不是函式指標。 運行時間通常會將這些函式指標轉換成小型 Thunk,讓 Unmanaged 程式代碼回呼至 Managed 程式代碼。
在Mono中,這些網橋是由 Just-In-Time 編譯程式實作。 使用 i 所需的預先編譯程式時 電話 此時有兩個重要的限制:
- 您必須使用 MonoPInvokeCallbackAttribute來標記所有回呼方法
- 方法必須是靜態方法,不支持實例方法。
無遠端處理
Xamarin.iOS 上無法使用遠端堆疊。
運行時間停用功能
Mono 的 iOS 執行時間中已停用下列功能:
- 分析工具
- 反思。發出
- 反思。Emit.Save 功能
- COM 系結
- JIT 引擎
- 中繼資料驗證器(因為沒有 JIT)
.NET API 限制
公開的 .NET API 是完整架構的子集,因為iOS 中無法使用所有專案。 如需目前支援的元件清單,請參閱常見問題。
特別是 Xamarin.iOS 所使用的 API 設定檔不包含 System.Configuration,因此無法使用外部 XML 檔案來設定運行時間的行為。