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

SwiftData属性赋值随机失败问题求助

SwiftData属性赋值随机触发EXC_BAD_ACCESS错误

问题详情

我有一个SwiftData模型类Digimon,包含如下属性:

var dimObject : DIM?

在为该属性赋值DIM对象时,会随机触发内存错误:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x8000000000000010)

错误触发的对象没有固定规律,且无额外报错信息。已定位到问题代码在insertDigimon函数中:

digimon.dimObject = dimFound

注释该行后错误消失,且赋值时digimon和dimFound均为非空对象,数据符合预期。

相关类定义

DIM类(SwiftData模型)

import Foundation
import SwiftData
import SwiftUI

@Model
class DIM: ObservableObject, Identifiable {
    @Attribute(.unique) var id: String
    var name: String
    var image: Data?
    
    init(id: String, name: String, image: Data? = nil) {
        self.id = id
        self.name = name
        self.image = image
    }
}

Digimon类(SwiftData模型)

import Foundation
import SwiftData
import SwiftUI

@Model
class Digimon: ObservableObject, Identifiable {
    @Attribute(.unique) var id: String
    var name: String
    var level: String
    var dimObject: DIM?
    
    init(id: String, name: String, level: String, dimObject: DIM? = nil) {
        self.id = id
        self.name = name
        self.level = level
        self.dimObject = dimObject
    }
}

列表视图代码

import SwiftUI
import SwiftData

struct DigimonListView: View {
    @Environment(\.modelContext) private var context
    @Query private var digimons: [Digimon]
    
    var body: some View {
        List(digimons) { digimon in
            VStack(alignment: .leading) {
                Text(digimon.name)
                Text(digimon.level)
                if let dim = digimon.dimObject {
                    Text(dim.name)
                }
            }
        }
        .toolbar {
            Button("Add Digimon") {
                insertDigimon()
            }
        }
    }
    
    private func insertDigimon() {
        let dimFound = DIM(id: "1", name: "Test DIM")
        let newDigimon = Digimon(id: UUID().uuidString, name: "Agumon", level: "Rookie")
        newDigimon.dimObject = dimFound // 问题触发行
        context.insert(newDigimon)
        do {
            try context.save()
        } catch {
            print(error.localizedDescription)
        }
    }
}

排查解决方向

  1. 修正SwiftData关联定义:当前dimObject是普通可选属性,SwiftData中模型间关联需用@Relationship标记,改为:

    @Relationship(deleteRule: .nullify) var dimObject: DIM?
    

    明确模型间的关系,让SwiftData正确管理对象生命周期。

  2. 确保上下文线程安全:所有SwiftData对象的操作必须在其所属的模型上下文线程中执行。如果dimFound是从其他线程获取的,需用context.perform切换到当前上下文:

    context.perform {
        newDigimon.dimObject = dimFound
        context.insert(newDigimon)
        try? context.save()
    }
    
  3. 移除重复的ObservableObject继承:SwiftData的@Model标记类本身已具备可观察特性,无需额外继承ObservableObject,移除两个类的该继承:

    @Model
    class DIM: Identifiable {
        // ... 属性定义
    }
    

    重复继承可能导致内存管理冲突。

  4. 用Xcode工具检测内存问题:开启Thread Sanitizer(Product > Scheme > Edit Scheme > Run > Diagnostics > Thread Sanitizer)捕捉多线程访问冲突;开启Zombie Objects检测,确认是否存在已释放对象的野指针访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:39:51