You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity使用Application.persistentDataPath读写编辑器正常iOS端报错如何解决

问题根因

  • 首次启动App无缓存文件时,RetrieveSavedModes方法未对savedModes做初始化兜底,直接返回null,后续访问.Count属性触发空引用
  • 未处理反序列化失败场景:as转换失败时storedModesFile为null,直接赋值给savedModes同样会触发空引用,iOS IL2CPP裁剪常导致自定义类序列化失败,Editor Mono环境无此问题
  • 文件操作未正确释放资源,易触发之前遇到的IO路径冲突错误
  • 硬编码路径分隔符存在跨平台兼容风险

修复方案

1. 修正读写逻辑,增加空兜底、资源自动释放、异常捕获

// 统一缓存路径,避免重复拼写错误
private readonly string SaveFilePath = Path.Combine(Application.persistentDataPath, "UserCustomModes.jl");

public void SaveModes()
{
    // 空值兜底,避免序列化null
    if (savedModes == null) savedModes = new List<Mode>();
    try
    {
        BinaryFormatter bf = new BinaryFormatter();
        // using自动释放FileStream,无需手动Close
        using (FileStream file = File.Create(SaveFilePath))
        {
            bf.Serialize(file, savedModes);
        }
    }
    catch (Exception e)
    {
        Debug.LogError($"Save failed: {e.Message}");
    }
}

public List<Mode> RetrieveSavedModes()
{
    // 先初始化兜底,避免任何异常场景返回null
    savedModes = new List<Mode>();
    if (File.Exists(SaveFilePath))
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream file = File.Open(SaveFilePath, FileMode.Open))
            {
                var storedData = bf.Deserialize(file);
                // 校验反序列化结果是否合法
                if (storedData is List<Mode> storedModesFile)
                {
                    savedModes = storedModesFile;
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Load failed: {e.Message}");
            // 读取失败时删除损坏的缓存文件,避免后续持续报错
            if (File.Exists(SaveFilePath)) File.Delete(SaveFilePath);
        }
    }
    return savedModes;
}

2. 处理iOS IL2CPP裁剪问题

给自定义的Mode类添加序列化标记和防裁剪标记,避免IL2CPP裁剪掉序列化需要的元数据:

[Serializable]
[UnityEngine.Scripting.Preserve]
public class Mode
{
    // 原有类成员不变
}

3. 可选校验逻辑

可在LoadSavedModes方法中增加空校验,进一步规避风险:

private void LoadSavedModes()
{
    RemoveAllModeButtons();
    Manager.savedModes = Manager.RetrieveSavedModes() ?? new List<Mode>();
    Debug.Log("[UNITY] Retrieve Modes Count: " + Manager.savedModes.Count);
    PopulateModeView();
}

内容的提问来源于stack exchange,提问作者RobertH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:54:03