我已经在项目中多次使用Json.Net来保存数据,并且从不担心为我的序列化类创建无参数构造函数。
现在,我正在从事一个适合这种情况的项目。它使用Json.Net来序列化一些没有无参数构造函数的类,并且可以正常工作。但是,一位同事警告我,我很幸运从未遇到任何问题,并且错误ExecutionEngineException: Attempting to JIT compile method
可能会出现并随时在iOS版本中使我的应用程序崩溃。
我看过很多关于Json.Net和Constructors或Json.Net和AOT的主题,但是没有关于Json.Net,Constructors和AOT的话题。这个世纪至少没有。
所以,我的问题是,我应该担心我的iOS设备中没有无参数构造函数的序列化类吗?
编辑:我的类具有构造函数,但它们接收自变量。我想知道是否需要除构造函数之外没有参数的构造器。
答案 0 :(得分:0)
如评论中所述,您只需要担心字节码剥离,而不是有关默认构造函数数量的任何事实。
Newtonsoft.Json的实例化类型的反射部分是不可避免的,因此要保护所有类免于字节码剥离,您有两个选择。
任一方式之一:禁用通过link.xml
文件进行字节码剥离。示例:
<linker>
<assembly fullname="MyAssembly">
<type fullname="MyAssembly.MyCSharpClass" />
</assembly>
</linker>
我发现Unity的官方文档比较分散并且缺乏,所以我重写了一些文档。
在此处详细了解如何使用link.xml
文件:https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Fix-AOT-using-link.xml
^基于逆向工程的UnityLinker和现有文档的行为。要进一步阅读,请访问:
选项2:通过Preserve
属性禁用字节码剥离。
向您的类,方法,字段,属性,事件或名称空间添加属性将确保UnityLinker不会剥离该属性。该属性必须命名为PreserveAttribute
,因此使用UnityEngine.Scripting.PreserveAttribute
或您自己的名为PreserveAttribute
的属性将产生相同的结果。
using UnityEngine.Scripting;
[Preserve]
public class YourTypeWithSpecialConstructor
{
public YourTypeWithSpecialConstructor(int value1, string value2)
{
}
}
了解有关Preserve
属性用法的更多信息:https://docs.unity3d.com/ScriptReference/Scripting.PreserveAttribute.html(我还没有重写它:p)
选项3:在我的Newtonsoft.Json for Unity版本中使用AotHelper。
Assets Store上的JSON .NET for Unity包基于Newtonsoft.Json 8.0.3,但是在编写本文时,我的当前是Newtonsoft.Json 12.0.3的最新版本,并通过Unity交付包管理器可以更轻松地保持最新状态: https://github.com/jilleJr/Newtonsoft.Json-for-Unity#readme
它包括 Newtonsoft.Json.Utilities 。 AotHelper 类,该类不仅禁用字节码剥离,而且还强制执行某些类型的编译,这在以下情况下非常有用涉及泛型。用法示例:
using Newtonsoft.Json.Utilities;
using UnityEngine;
public class AotTypeEnforcer : MonoBehaviour
{
public void Awake()
{
AotHelper.Ensure(() => {
_ = new YourGenericTypeWithSpecialConstructor<int>(0, null);
_ = new YourGenericTypeWithSpecialConstructor<float>(0, null);
_ = new YourGenericTypeWithSpecialConstructor<string>(null, null);
_ = new YourGenericTypeWithSpecialConstructor<bool>(true, null);
});
}
}
public class YourGenericTypeWithSpecialConstructor<T>
{
public YourGenericTypeWithSpecialConstructor(T value1, string value2)
{
}
}
在此处详细了解如何使用AotHelper:https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Fix-AOT-using-AotHelper