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

Core Data复制对象后修改新对象data属性同步变更原对象问题

问题根源
  • name属性属于值类型,赋值时会自动执行值拷贝,新老对象的name从赋值完成开始就完全独立,修改互不影响。
  • data属性是存储自定义类实例的数组:Swift中的数组虽然是值类型,但仅会拷贝数组本身的结构,数组内存储的类实例依然是引用传递,指向同一块内存地址。同时Core Data的Transformable类型仅在持久化读写时执行归档解档,内存中直接赋值不会自动触发深拷贝,因此你修改新对象data数组中的元素时,原对象的data也会同步变化。
修复步骤
  1. 给自定义类实现NSCopying协议
    你data数组里的自定义对象需要支持拷贝,确保每个实例可以生成完全独立的副本,示例如下(请替换成你自己的自定义类属性):
// 假设你的自定义类名为CustomDataModel
class CustomDataModel: NSObject, NSCopying, NSSecureCoding {
    // 你的自定义属性
    var param1: String
    var param2: Int

    // NSCopying协议实现
    func copy(with zone: NSZone? = nil) -> Any {
        let copiedInstance = CustomDataModel(param1: self.param1, param2: self.param2)
        // 如果有嵌套的类属性,也要在这里执行拷贝赋值
        return copiedInstance
    }

    // Transformable属性要求的NSSecureCoding实现,原有逻辑保留即可
    static var supportsSecureCoding: Bool = true
    func encode(with coder: NSCoder) {
        coder.encode(param1, forKey: "param1")
        coder.encode(param2, forKey: "param2")
    }
    required init?(coder: NSCoder) {
        guard let p1 = coder.decodeObject(of: NSString.self, forKey: "param1") as? String else { return nil }
        param1 = p1
        param2 = coder.decodeInteger(forKey: "param2")
    }
    init(param1: String, param2: Int) {
        self.param1 = param1
        self.param2 = param2
    }
}
  1. 替换data属性的赋值逻辑
    不要直接赋值原对象的data,改为遍历数组逐个拷贝元素后生成新数组赋值:
// 把原来的 object.data = initialObject.data 替换为以下代码
if let originalData = initialObject.data as? [CustomDataModel] {
    let copiedData = originalData.map { $0.copy() as! CustomDataModel }
    object.data = copiedData
}

如果你的自定义类中还嵌套了其他引用类型的属性,需要给所有嵌套的类都实现NSCopying协议,逐层完成深拷贝,才能保证两个对象的data属性完全独立。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:12:00