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

Swift使用RealmSwift创建Object时触发EXC_BAD_ACCESS错误(已更新配置)

RealmSwift 频繁触发 EXC_BAD_ACCESS 错误

我已修正Realm的配置定义,但仍出现错误。使用Swift和RealmSwift开发小型App时,写入数据库有时可行,但读取对象时频繁触发Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)错误。

RealmManager类(创建Realm实例)

import RealmSwift
import Foundation

class RealmManager {
  private var configured: Bool

  private var init(){
    self.configured = false
  }

  static let shared = RealmManager()

  lazy var realm: Realm = {
    if !self.configured {
      var config = Realm.Configuration.defaultConfiguration
      let realm = try! Realm(configuration: config)
    } else {
      let realm = try! Realm()
    }
    return realm
  }

  func configure() throws {
    let dbName = "MyApp.realm"
    var dbConf = Realm.Configuration()

    guard let url = dbConf.fileURL?.deletingLastPathComponent().appendingLastPathComponent(dbName) else {
      throw DBError.databaseNameError
    }
    dbConf.fileURL = url
    dbConf.readOnly = false
    dbConf.schemaVersion = 1
    do {
      self.realm = try Realm(configuration: dbConf)
      self.configured = true
    } catch {
      throw DBError.configurationError
    }
  }

AppDelegate中调用RealmManager的代码

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
  var window: UIWindow
  var realmM: Realm!
  var pushToken: String = ""

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions : [UIApplication.LaunchOptionsKey: Any]?)-> Bool {
    self.realmM = openRealm()
    return true
  }

  private func openRealm() -> Realm {
    do {
      try RealmManager.shared.configure()
    } catch {
      print("Didnt configure Realm")
    }
    let realm = RealmManager.shared.realm
    return realm
  }
}

触发错误的Realm Object定义

import Foundation
import RealmSwift

class Carga: Object{
  @Persisted(primaryKey: true) var idCarga : Int32
  @Persisted var idPedido : Int32
  @Persisted var units : Int32
  @Persisted var packages : Int32
  @Persisted var kilograms : Double

  convenience init(_id: Int32, idPedido: Int32, uds: Int32, pkgs: Int32, kgs: Double) {
    self.init()
    self.idCarga = _id
    self.idPedido = idPedido
    self.units = uds
    self.packages = pkgs
    self.kilograms = kgs
  }
}

class Pedido : Object{
  @Persisted(primaryKey: true) var idPedido : Int32
  @Persisted var idLugar : Int32
  @Persisted var cargas = RealmSwift.List<Carga>()  // Thread 1: EXC_BAD_ACCESS (code=1,adress=0x0)

  convenience init(_id: Int32, idLugar: Int32, listCargas: RealmSwift.List<Carga>) {
    self.init()
    self.idPedido = _id
    self.idLugar = idLugar
    self.cargas = listCargas
  }
}

class Lugar : Object{
  @Persisted(primaryKey: true) var idLugar : Int32
  @Persisted var name : String
  @Persisted var pedidos = RealmSwift.List<Pedido>()  // Thread 1 :EXC_BAD_ACCESS (code=1,adress=0x0)

  convenience init(_id: Int32, name: String, listPedidos: RealmSwift.List<Pedido>) {
    self.init()
    self.idLugar = _id
    self.name = name
    self.pedidos = listPedidos
  }
}

补充说明

  • ID定义为Int32是为了适配Firebase的Int32格式。
  • 错误出现的执行路径:
    1. RealmManager中self.realm = try Realm(configuration: dbConf)
    2. Realm类的Realm.init()
    3. RLMObjectSchema的getProperties(_:)
    4. Object初始化(Pedido.init()、Carga.init())
    5. Object属性定义(@Persisted var cargas = RealmSwift.List<Carga>()等)

问题分析与解决方案

1. RealmManager核心错误修正

你的realm懒加载闭包存在两个致命问题:闭包内创建的realm是局部变量,未返回导致野指针;直接给self.realm赋值破坏懒加载逻辑。修正后代码:

import RealmSwift
import Foundation

enum DBError: Error {
    case databaseNameError
    case configurationError
}

class RealmManager {
    private var configured: Bool = false
    private(set) var realm: Realm?
    
    static let shared = RealmManager()
    
    private init() {}
    
    func configure() throws {
        let dbName = "MyApp.realm"
        var dbConf = Realm.Configuration()
        
        guard let url = dbConf.fileURL?.deletingLastPathComponent().appendingPathComponent(dbName) else {
            throw DBError.databaseNameError
        }
        dbConf.fileURL = url
        dbConf.readOnly = false
        dbConf.schemaVersion = 1
        dbConf.migrationBlock = { migration, oldSchemaVersion in
            if oldSchemaVersion < 1 {}
        }
        
        do {
            self.realm = try Realm(configuration: dbConf)
            self.configured = true
        } catch {
            throw DBError.configurationError
        }
    }
}

2. AppDelegate调用逻辑优化

避免访问未配置的Realm实例,增加空值判断:

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
    var window: UIWindow?
    var realmM: Realm?
    var pushToken: String = ""

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions : [UIApplication.LaunchOptionsKey: Any]?)-> Bool {
        self.realmM = openRealm()
        return true
    }

    private func openRealm() -> Realm? {
        do {
            try RealmManager.shared.configure()
            return RealmManager.shared.realm
        } catch {
            print("Realm配置失败: \(error)")
            return nil
        }
    }
}

3. Realm Object定义修复

@Persisted修饰的List无需手动初始化,便利初始化器中不能直接赋值List,需通过append添加元素:

import Foundation
import RealmSwift

class Carga: Object{
    @Persisted(primaryKey: true) var idCarga: Int32
    @Persisted var idPedido: Int32
    @Persisted var units: Int32
    @Persisted var packages: Int32
    @Persisted var kilograms: Double

    convenience init(_id: Int32, idPedido: Int32, uds: Int32, pkgs: Int32, kgs: Double) {
        self.init()
        self.idCarga = _id
        self.idPedido = idPedido
        self.units = uds
        self.packages = pkgs
        self.kilograms = kgs
    }
}

class Pedido : Object{
    @Persisted(primaryKey: true) var idPedido: Int32
    @Persisted var idLugar: Int32
    @Persisted var cargas: RealmSwift.List<Carga>

    convenience init(_id: Int32, idLugar: Int32, listCargas: [Carga]) {
        self.init()
        self.idPedido = _id
        self.idLugar = _id
        self.cargas.append(contentsOf: listCargas)
    }
}

class Lugar : Object{
    @Persisted(primaryKey: true) var idLugar: Int32
    @Persisted var name: String
    @Persisted var pedidos: RealmSwift.List<Pedido>

    convenience init(_id: Int32, name: String, listPedidos: [Pedido]) {
        self.init()
        self.idLugar = _id
        self.name = name
        self.pedidos.append(contentsOf: listPedidos)
    }
}

4. 额外注意事项

  • 所有Realm操作必须在同一线程执行,实例和对象不能跨线程访问。
  • 写入操作必须放在try! realm.write { }闭包内。
  • 可添加错误监听辅助排查:
Realm.Configuration.defaultConfiguration.errorHandler = { error, isFatal in
    print("Realm错误: \(error), 是否致命: \(isFatal)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:00:01