知乎的一個提問:unity3d跨平臺原理ios
一些資料:c#
IL是.NET框架中中間語言(Intermediate Language)的縮寫。使用.NET框架提供的編譯器能夠直接將源程序編譯爲.exe或.dll文件,但此時編譯出來的程序代碼並非CPU能直接執行的機器代碼,而是一種中間語言IL(Intermediate Language)windows
Xamarin(現以被微軟收購)是mono項目的一個分支,但這裏面最大的區別Xamarin是商業項目.mono作爲跨平臺的框架已獲得愈來愈多的商業項目的確定,令外界擔憂的版權問題\可靠性\穩定性也獲得證明,使用mono最大的好處是可使用其它平臺衆多的項目解決方案,而沒必要被限制在windows平臺下貧乏而又昂貴的各類解決方案.bash
在Mac OS上,由於iOS的現有限制,面向iOS的C#代碼會經過AOT編譯技術直接編譯爲ARM彙編代碼。而在Android上,應用程序會轉換爲IL,啓動時再進行JIT編譯。框架
調試時遇到一個Mono運行時異常:函數
1
2
|
ExecutionEngineException: Attempting to JIT compile method
'...'
while
running with --aot-only.
|
最後發現緣由是使用了泛型接口,致使Mono須要JIT編譯,但在iOS平臺中,Mono是以Full AOT模式運行的,沒法使用JIT引擎,因而引起了這個異常。優化
Mono的AOT和.NET的Ngen同樣,都是經過提早編譯來減小JIT的工做,但默認狀況下AOT並不編譯全部IL代碼,而是在優化和JIT之間取得一個平衡。因爲iOS平臺禁止JIT編譯,因而Mono在iOS上須要Full AOT編譯和運行。即預先對程序集中的全部IL代碼進行AOT編譯生成一個本地代碼映像,而後在運行時直接加載這個映像而再也不使用JIT引擎。目前因爲技術或實現上的緣由在使用Full AOT時有一些限制,具體能夠參考MonoTouch的文檔,這裏提幾條常見的:spa
不支持泛型虛方法,由於對於泛型代碼,Mono經過靜態分析以肯定要實例化的類型並生成代碼,但靜態分析沒法肯定運行時實際調用的方法(C++也所以不支持虛模版函數)。設計
不支持對泛型類的P/Invoke。3d
目前不能使用反射中的Property.SetInfo給非空類型賦值。
值類型做爲Dictionary的Key時會有問題,實際上實現了IEquatable<T>的類型都會有此問題,由於Dictionary的默認構造函數會使用EqualityComparer<TKey>.Default做爲比較器,而對於實現了IEquatable<T>的類型,EqualityComparer<TKey>.Default要經過反射來實例化一個實現了IEqualityComparer<TKey>的類(能夠參考EqualityComparer<T>的實現)。 解決方案是本身實現一個IEqualityComparer<TKey>,而後使用Dictionary<TKey, TValue>(IEqualityComparer<TKey>)構造器建立Dictionary實例。
因爲不容許動態生成代碼,不容許使用System.Reflection.Emit,不容許動態建立類型。
因爲不容許使用System.Reflection.Emit,沒法使用DLR及基於DLR的任何語言。
不要混淆了Reflection.Emit和反射,全部反射的API都可用
JIT:http://en.wikipedia.org/wiki/Just-in-time_compilation