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

Core Data中questionsCD.questions?.questionList赋值失败 读取时返回nil

故障原因&解决方案

核心故障根因

  1. 新建的QuestionCD实例的questions属性默认是nil,你直接对questionsCD.questions?.questionList赋值属于对可选链的nil节点赋值,赋值操作会直接被忽略,没有任何效果。
  2. 嵌套自定义类QuestionList未实现NSSecureCoding协议,NSSecureCoding解码时无法识别该类的实例,导致解码失败返回nil。
  3. QuestionsValueTransformer的允许顶级类配置不全,缺少解码所需的NSArray和QuestionList类声明。
  4. 若未在Core Data初始化前注册QuestionsValueTransformer,Core Data无法识别转换器,会直接丢弃对应属性值。

修复步骤

1. 修改保存逻辑,初始化QuestionsNSSecureCoding实例

将saveSelectedQuestion函数中的赋值代码替换为:

// 先创建QuestionsNSSecureCoding实例,再赋值给questions属性
questionsCD.questions = QuestionsNSSecureCoding(questions: questions)

2. 给QuestionList实现NSSecureCoding协议

修改QuestionList类代码:

class QuestionList: Codable, Identifiable, NSSecureCoding {
    public static var supportsSecureCoding: Bool = true
    
    var id: String
    
    init(id: String) {
        self.id = id
    }
    
    public func encode(with coder: NSCoder) {
        coder.encode(id as NSString, forKey: "id")
    }
    
    required public init?(coder: NSCoder) {
        guard let id = coder.decodeObject(of: NSString.self, forKey: "id") as? String else {
            return nil
        }
        self.id = id
    }
}

3. 补充QuestionsValueTransformer的允许类列表

修改allowedTopLevelClasses属性:

override static var allowedTopLevelClasses: [AnyClass] {
    return [QuestionsNSSecureCoding.self, NSArray.self, QuestionList.self]
}

4. 确保提前注册转换器

在App启动阶段、Core Data栈初始化前调用注册方法,例如下放在AppDelegate的didFinishLaunchingWithOptions方法中:

QuestionsValueTransformer.register()

可选优化

可以优化QuestionsNSSecureCoding的解码逻辑,提升兼容性:

required public init?(coder: NSCoder) {
    guard let list = coder.decodeArrayOfObjects(of: [QuestionList.self], forKey: "questionList") else {
        questionList = []
        return
    }
    questionList = list
}

内容的提问来源于stack exchange,提问作者Ufuk Köşker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:18:03