1

so there are tons of same question but none of them helped me that's why i'm asking the same question again, so i'm getting this Exception while accessing an Array of RealmObject. when i checked similar question and Realm's official website i found on thing similar in every question

Realm objects are not thread safe and cannot be shared across threads, so you must get a Realm instance in each thread/dispatch queue in which you want to read or write.

so what i did is i created new instances of Realm before accessing it

here's some snippet:

        let realm = try! Realm()
        try! realm.write {
            realm.add(saveUserCredentials, update:  true)
           }

i created a new Instance everytime before accessing realm, something like i stated at above

still i was getting the same error then i tried to access my Realm Instance on only MainThread, i did something like:

if Thread.isMainThread{
    let realm = try! Realm()
    try! realm.write {
        realm.add(saveUserCredentials, update:  true)
     }
 }else{
    DispatchQueue.main.async {
         let realm = try! Realm()
        try! realm.write {
            realm.add(saveUserCredentials, update:  true)
         }
    }}

still i'm getting the same error

fatal error: unexpectedly found nil while unwrapping an Optional value libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread. (lldb)

and i'm pretty sure what i'm doing is not the correct way to do it, and the error is occurring not so often, 1 out of 10 times

anyone can point out what's exactly i have to do for handling this Exception?

Jano
  • 62,815
  • 21
  • 164
  • 192
21 pilots
  • 21
  • 1
  • 4
  • is `saveUserCredentials` a managed object? What thread was it acquired on? – EpicPandaForce Apr 27 '17 at 07:23
  • @EpicPandaForce what you mean by managed object? and it's not clear in which Thread its acquiring on, cause i'm calling this method `saveUserCredentials()` which basically creates this `saveUserCredentials` object and i'm calling my method after executing some Async Tasks (they're performing some network requests ) – 21 pilots Apr 27 '17 at 07:28
  • Managed object means it has been added to Realm and became a managed proxy. Then it is bound to the thread where the Realm you added it to was opened on. You might want to try wrapping `saveUserCredentials` into a `ThreadSafeReference`, although the mistake is probably more fundamental. – EpicPandaForce Apr 27 '17 at 08:12

2 Answers2

1

Realm objects are not thread safe and cannot be shared across threads, so you must get a Realm instance in each thread/dispatch queue in which you want to read or write.

Realm objects means Realm, Objects, Results, List and LinkingObjects. saveUserCredentials is instance of Objects or List right? So you cannot pass saveUserCredentials accross threads. To resolve this, you can wrap it by ThreadSafeReference then pass it accross threads, or re-fetch saveUserCredentials each thread as well as realm

See also https://realm.io/docs/swift/latest/#threading

kishikawa katsumi
  • 10,418
  • 1
  • 41
  • 53
0

Since your root concern is how to handle threading in Realm, you may be interested in using a value typed api that keeps realm objects inside the boundaries of your persistence layer. There are pros and cons that may fit your use case or not. You could also use both value and realm native types in different parts of a single project depending on your use case.

Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192