线程 1:异常:"Realm accessed from incorrect thread."

Thread 1: Exception: "Realm accessed from incorrect thread."

我有两种看法。第一个显示由下载数据组成的自定义对象列表,第二个显示作为第一个列表中对象基础的对象列表。

如果我在第二个视图中选择一个对象保存在 Realm 中并返回到第一个视图,则从数据库下载用于制作自定义对象列表的数据。如果我想删除该对象,应用程序会崩溃并出现此消息:

Thread 1: Exception: "Realm accessed from incorrect thread."

同样的情况是当我在第一个屏幕删除一个,两个或多个对象时,转到另一个,选择一个,两个或多个保存在数据库中并返回到第一个,其中数据从数据库下载。应用程序崩溃并显示相同的消息。

我知道这都是关于线程的,但我不知道如何解决。 我尝试通过 DispatchQueue 解决该问题,但它不起作用,或者我做错了。如何解决我的线程问题?

第一个视图中正在使用这些数据库函数:

 func deleteAddItem(addItem: AddItem) throws {
    do {
       let realm = try! Realm()
        try! realm.write {
            if let itemToDelete = realm.object(ofType: AddItem.self, forPrimaryKey: addItem.id) {
                realm.delete(itemToDelete)
                realm.refresh()
            }
        }
    }
    }
}
    
func fetchStations() throws -> Results<Station> {
        do {
            realm = try Realm()
            return realm!.objects(Station.self)
        }
        catch {
            throw RuntimeError.NoRealmSet
        }
    }

func fetchSensors() throws -> Results<Sensor> {
    do {
        realm = try Realm()
        return realm!.objects(Sensor.self)
    }
    catch {
        throw RuntimeError.NoRealmSet
    }
  }

func fetchAddItems() throws -> Results<AddItem> {
    do {
        realm = try Realm()
        return realm!.objects(AddItem.self)
    }
    catch {
        throw RuntimeError.NoRealmSet
    }
}

func fetchData() throws -> Results<Data> {
    do {
        realm = try Realm()
        return realm!.objects(Data.self)
    }
    catch {
        throw RuntimeError.NoRealmSet
}
    }

如果您需要更多代码或信息,请告诉我。

您似乎有两个不同的 Realm 线程在运行

 func deleteAddItem(addItem: AddItem) throws {
     do {
        let realm = try! Realm()  <- One realm thread, a local 'let'

然后

func fetchAddItems() throws -> Results<AddItem> {
    do {
        realm = try Realm()   <- A different realm thread, a class var?

删除时使用相同的领域可能可以解决这个问题

 func deleteAddItem(addItem: AddItem) throws {
     do {
        realm = try! Realm()  <- references the same realm as in delete

几乎没有什么方法可以防止这种情况发生。一次就是简单的获取境界,每次想用就用

let realm = try! Realm()
realm.read or realm.write etc

或者创建一个可以在整个应用程序中访问的单例函数(或 RealmService class)。在一个单独的文件中(或者你想把它放在什么地方,这只是一个简单的例子)

import RealmSwift

func gGetRealm() -> Realm? {
    do {
        let realm = try Realm()
        
        return realm
    } catch let error as NSError { //lots of error handling!
        print("Error!")
        print("  " + error.localizedDescription)
        let err = error.code
        print(err)
        let t = type(of: err)
        print(t)
        return nil
    }
}

然后使用它

if let realm = gGetRealm() {    
   realm.read, realm.write etc 
}

此外,我注意到您似乎正在从领域获取一个项目,然后将其删除。没必要。

如果项目已经被Realm管理,直接删除即可。这是一个更新的删除功能

func deleteItem(whichItem: theItemToDelete) {
   if let realm = gGetRealm() {
      try! realm.write {
         realm.delete(theItemToDelete)
      } 
   }
}