unity使用序列化在mac上正常運行 ios真機上拋出異常
ExecutionEngineException: Attempting to JIT compile method '...' while running with --aot-only.
網上搜的原因:
1.
使用了泛型接口,導致Mono需要JIT編譯,但在iOS平臺中,Mono是以Full AOT模式運行的,無法使用JIT引擎,於是引發了這個異常。
JIT的涵意是,實時生成NativeCode。
Mono的AOT和.NET的Ngen一樣,都是通過提前編譯來減少JIT的工作,但默認情況下AOT並不編譯所有IL代碼,而是在優化和JIT之間取得一個平衡。由於iOS平臺禁止JIT編譯,於是Mono在iOS上需要Full AOT編譯和運行。即預先對程序集中的所有IL代碼進行AOT編譯生成一個本地代碼映像,然後在運行時直接加載這個映像而不再使用JIT引擎。目前由於技術或實現上的原因在使用Full AOT時有一些限制,具體可以參考MonoTouch的文檔,這裏提幾條常見的:
- 不支持泛型虛方法,因爲對於泛型代碼,Mono通過靜態分析以確定要實例化的類型並生成代碼,但靜態分析無法確定運行時實際調用的方法(C++也因此不支持虛模版函數)。
- 不支持對泛型類的P/Invoke。
- 目前不能使用反射中的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均可用。
- See more at: http://ravenw.com/blog/2011/11/08/limitations-of-mono-with-full-aot/#sthash.Wi5sL8EL.dpuf
鏈接:http://www.cnblogs.com/tekkaman/p/3973452.html
2.
查閱資料地址
http://wiki.unity3d.com/index.php?title=Saving_and_Loading_Data:_XmlSerializer
問題解決:
iOS Devices
A NullReferenceException will be raised if you're using List<T> in your MonsterContainer class, use an array instead. Similarly the same exception is raised if you're using get and set to implement properties in the class you're trying to serialize.
在IOS上不能使用List<T>的類型,需要使用數組。在XML序列化屬性的get、set方法中,也不能使用List<T>。
鏈接:http://blog.csdn.net/rcfalcon/article/details/46864125
3.
Unity 跨平臺發佈的優勢是顯而易見的.但還是會有一些坑.尤其是在IOS真機上.關於JIT的問題還是比較棘手的.
而且是在unity中和模擬器中都是好的,一運行在真機上就出問題.
當運行中遇到
ExecutionEngineException: Attempting to JIT compile method '...' while running with --aot-only.
的錯誤時.說明有有代碼使用了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的文檔,這裏提幾條常見的:
- 不支持泛型虛方法,因爲對於泛型代碼,Mono通過靜態分析以確定要實例化的類型並生成代碼,但靜態分析無法確定運行時實際調用的方法(C++也因此不支持虛模版函數)。
- 不支持對泛型類的P/Invoke。
- 目前不能使用反射中的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實例。
- BinaryFormatter 使用 Serialize 時.如果需要對List等容器進行Serialize.
需要在代碼中加入 System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
- Property 不能使用 GetValue.FiledInfo 可以正常使用 可以使用Property的GetGetMethod().Invoke
來替代.我的上一篇文章中初始化粒子對象中有用到.
- crateinstence 帶參數不能超過9個.呵呵.這個是我一點點試出來的..
- bytestoStruct 不能應用於 class
鏈接:http://m.blog.csdn.net/blog/ainn_pp/42268585