Realm Accessed from Incorrect Thread

Realm accessed from incorrect thread Swift

I'm not familiar with Realm but it appears that you may have to call it from the main thread? Try printing out the current thread in your log (Thread.current) to see if your on a background one.

If thats the case wrap your execute/add calls in DispatchQueue.main.async(execute: {}) to see if that fixes the issue?

RLMException', reason: 'Realm accessed from incorrect thread.'

Using a Singleton does not mean that it will always be called on the same thread... for example..

// 1. here you are likely in the main thread
URLSession.shared.dataTask(with: urlRequest) { (data, response, err) in
// 2. here you are in a background thread
}

Your singleton (databaseManager) has likely been created on the main thread. When you are within a closure of an asynchronous function as in point 2 above, you are in a background thread. So if you create the objects in the background thread and then pass it to databaseManager to save, you are passing an object created on a background thread, to a realm instance that was created on the main thread. Causing your issue.

If I remember rightly, you should be able to dispatch to the main thread within the closure and get rid of this error:

DispatchQueue.main.async {
let json = try! JSONSerialization.jsonObject(with: content, options: .allowFragments) as! [String:AnyObject]
let ersonJson = json["data"] as! AnyObject
let tmp = Mapper<person>().map(JSONObject: ersonJson)!
tmp.serverToken = db.serverToken

self.dbManager.deleteAllFromDatabase()
if self.dbManager.saveData(ps: tmp) {

}
}

Realm accessed from incorrect thread - Swift 3

It seems like the write is happening on a different thread than the object was originally accessed from. You should be able to fix it by passing task's id and using that to fetch it from the database right before you do the write (inside the async block).

So at the top:

var taskId = 0  // Set this accordingly

and then something like

self.queue.async {
autoreleasepool {
let realm = try! Realm()
let tempTask = // get task from Realm based on taskId
realm.beginWrite()
realm.delete(tempTask)
do {
try realm.commitWrite()
} catch let error {
self.presentError()
}
}
}

Thread 1: Exception: Realm accessed from incorrect thread.

It appears you have two different Realm threads going

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

and then

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

that can probably be fixed by using the same realm when deleting

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

There are few options to prevent this. Once is simply get the realm, every time you want to use it

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

or create a singleton function (or a RealmService class) that can be accessed throughout the app. In a separate file (or whever you want to put it and this is just a quick example)

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
}
}

Then to use it

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

Also, I noticed you appear to be getting an item from realm to just then delete it. That's not necessary.

If the item is already managed by Realm, it can just be deleted directly. Here's an updated delete function

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

How to fix this issue `Realm accessed from incorrect thread.` in swift 4

This is the correct answer

searchBar.rx.text.orEmpty.debounce(0.3, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.filter { !$0.isEmpty }
.observeOn(MainScheduler.instance)
.subscribe(onNext: { (data) in
let realm = try! Realm()
let tcb = realm.objects(TrialCourtBranches.self)
let predicate = NSPredicate(format: "(branch_name CONTAINS[c] %@) OR (office_no CONTAINS[c] %@) OR (loc.pc.city_municipality CONTAINS[c] %@) OR (loc.pc.province CONTAINS[c] %@) OR (loc.address1 CONTAINS[c] %@)",data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased())
tcb_filteredArray = tcb.filter(predicate)
self.tableView.reloadData()
}, onError: { (errorResult) in
print(errorResult)
}, onCompleted: {
print("onCompleted")
}, onDisposed: {
print("onDisposed")
})
.disposed(by: bag)


Related Topics



Leave a reply



Submit