Realm Swift iOS - 由于未捕获的异常“RLMException”而终止应用程序,原因:“从不正确的线程访问领域”

kod*_*usz 1 exception object realm ios swift

我在 Swift 2.0 中从领域数据库加载对象时遇到问题。

我打电话:

    var cities = try! Realm().objects(City)
Run Code Online (Sandbox Code Playgroud)

我的应用程序崩溃了,我给出“由于未捕获的异常‘RLMException’而终止应用程序,原因:‘从不正确的线程访问领域’”

有没有人示例代码或教程我应该何时何地调用方法?

Jak*_*nin 6

领域以及该领域中的大多数对象只能从创建该领域的线程(即您执行类似操作的线程let realm = Realm())进行访问。

因此,当您在“线程 A”上创建领域时let realm = try Realm(),您只能从“线程 A”访问该领域。否则,您将收到 RLMException。

同样,对于大多数对象,如果您从“线程 A”上的该领域获取它,例如:var myCars = realm.objects(Car.self),那么您只能myCars在“线程 A”上使用您的对象。

一个快速解决方案(但绝对不是生产质量应用程序的最佳方法)是将所有内容都放入主队列中。这确保了所有领域的事情都发生在同一个线程上,但缺点是,如果您正在做一些繁重的工作,它会显着减慢您的应用程序的速度。在 swift 3 中,您可以通过以下方式执行此操作:

DispatchQueue.main.async{
    do{
        //your stuff.
        //ex:
        let realm = try Realm()
        myCars = try realm.objects(Car.self)
        if myCars != nil{
            try realm.write{
                for car in myCars!{
                    car.drive()
                }
            }
        }
    }catch{
        print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

更好的解决方案使用后台队列,然后在需要更新时返回主队列。您可以像这样创建后台队列:

let myRealmQueue = DispatchQueue(label: "realmQueue", qos: .background)

然后在这个队列上做你的领域的事情:

myRealmQueue.async{
    do{
        //Do your realm stuff in this queue.
        let realm = try Realm()
        myCars = try realm.objects(Car.self)
        if myCars != nil{
            let numberOfCars = myCars.count
            //return to main queue to update UI
            DispatchQueue.main.async{
                numberOfCarsLabel.text = numberOfCars
            }
        }
    }catch{
        print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您对 swift 中的线程不是很熟悉,我建议您至少花一两个小时在 google 上熟悉最佳实践。您很可能会找到比我提供的解决方案更好的解决方案。