AOT设备中Json.Net反序列化是否需要空构造函数



我已经在项目中使用Json.Net很多次来保存数据,而且从不担心为序列化类创建无参数构造函数。

现在我正在做一个适合这种情况的项目。它使用Json.Net序列化了一些没有无参数构造函数的类,并且运行良好。然而,一位同事警告我,我很幸运从未遇到过任何问题,并且在iOS构建中,ExecutionEngineException: Attempting to JIT compile method错误可能随时出现并使我的应用程序崩溃。

我看过很多关于Json.Net和Constructors或Json.Net与AOT的主题,但没有看到关于Json.Net、Constructors和AOT的内容。至少本世纪没有。

所以,我的问题是,我应该担心iOS设备中没有无参数构造函数的序列化类吗?

EDIT:我的类有构造函数,但它们接收参数。我想知道我是否需要没有参数的构造函数。

如注释中所述,您应该害怕的只是字节码剥离,而不是关于默认构造函数数量的任何事实。

Json实例化类型的反射部分是不可避免的,因此为了保护所有类不受字节码剥离的影响,您有几个选项。


任一1:通过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和现有文档的行为进行逆向工程。欲了解更多信息,请访问:

  • https://docs.unity3d.com/Manual/ManagedCodeStripping.html
  • https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html

选项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

相关内容

最新更新