unity 序列化在IOS真機上拋出異常

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章