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

Realm存储Integer类型致项目崩溃,寻求解决方案

崩溃原因排查与修复方案

嘿,我仔细看了你的代码和遇到的崩溃问题,大概率是Realm模型属性的声明方式踩坑了——虽然你跟着官方文档走,但可能没注意到一个关键细节:Realm对Swift基础数据类型的动态属性处理有特殊要求。

核心问题分析

你代码里的sets、reps、kg都是用@objc dynamic var xxx = 0声明的,但Realm在处理非可选的基础值类型(比如Int)时,直接用@objc dynamic会导致运行时的访问冲突。因为Realm需要通过自身的属性包装逻辑来管理这些持久化属性,普通的@objc dynamic无法被Realm正确拦截和处理,最终触发崩溃。

两种可行修复方案

方案1:使用Realm推荐的@Persisted属性(强烈推荐)

从Realm 10.x版本开始,官方推荐用@Persisted替代旧的@objc dynamic写法,这种方式能完美适配各种数据类型,包括非可选的基础类型。修改后的模型代码如下:

import Foundation
import RealmSwift

class Workout: Object {
    @Persisted var date: Date?
    @Persisted var exersice: String?
    @Persisted var sets = 0
    @Persisted var reps = 0
    @Persisted var kg = 0
    @Persisted var notes: String?
}

方案2:兼容旧写法(不推荐)

如果你暂时不想切换到新语法,可以把非可选的Int改成可选类型,让@objc dynamic能被Realm正确处理:

import Foundation
import RealmSwift

class Workout: Object {
    @objc dynamic var date: Date?
    @objc dynamic var exersice: String?
    @objc dynamic var sets: Int? = 0
    @objc dynamic var reps: Int? = 0
    @objc dynamic var kg: Int? = 0
    @objc dynamic var notes: String?
}

⚠️ 注意:这种方式会引入不必要的可选类型,后续处理数据时需要额外判断空值,增加复杂度,所以优先选方案1。

额外排查点:Realm架构迁移

如果你之前已经运行过旧版本的App(比如模型里还没有这些Int属性的时候),新增属性后没有配置迁移,也会导致崩溃。解决方法是在App启动时添加迁移配置:

// 在AppDelegate的didFinishLaunchingWithOptions里添加
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let config = Realm.Configuration(
        schemaVersion: 1, // 版本号要比之前的旧版本高
        migrationBlock: { migration, oldSchemaVersion in
            // 如果是从低于1的版本迁移,Realm会自动添加新属性,无需额外操作
            if oldSchemaVersion < 1 { }
        })
    Realm.Configuration.defaultConfiguration = config
    
    return true
}

最后验证步骤

改完代码后,记得删除模拟器里的App或者清空App沙盒数据,然后重新运行,避免旧的Realm数据库文件和新模型冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:22:34