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
相关产品推荐
相关产品推荐

