Swift使用realm.add()或realm.create()将大量数据写入领域

时间:2018-09-18 02:04:30

标签: ios swift realm

我需要将大量数据(例如200000输入)写入领域,并且我使用realm.add()在后台线程中写入数据。但是它收到了崩溃消息:

  

由于未捕获的异常“ RLMException”而终止应用程序,原因:“从错误的线程访问了领域。”

let cities = try decoder.decode([City].self, from: dataFromStream)
let dispatchQueue = DispatchQueue(label: "com.example.myApp.bg", qos: .background)
dispatchQueue.async {
    let myBackgroundRealm = try! Realm()
    myBackgroundRealm.beginWrite()

    for city in cities {
        myBackgroundRealm.add(city, update: false)
    }

    try! myBackgroundRealm.commitWrite()
}

因此,我更改为使用Realm.create(),它可以工作。但是我仍然不了解Realm.create()和Realm.add()在写入大数据方面有什么区别。

let cities = try decoder.decode([City].self, from: data)
let dispatchQueue = DispatchQueue(label: "com.example.myApp.bg", qos: .background)
dispatchQueue.async {
    let myBackgroundRealm = try! Realm()

    for city in cities {
        try! myBackgroundRealm.write {
            myBackgroundRealm.create(City.self, value: city, update: false)
        }
    }
}

2 个答案:

答案 0 :(得分:0)

在异步写入领域时,您必须初始化线程安全引用并在后台线程中解析该引用。取自领域文档https://realm.io/docs/swift/latest/#passing-instances-across-threads

let person = Person(name: "Jane")
try! realm.write {
    realm.add(person)
}
let personRef = ThreadSafeReference(to: person)
DispatchQueue(label: "background").async {
    autoreleasepool {
        let realm = try! Realm()
        guard let person = realm.resolve(personRef) else {
            return // person was deleted
        }
        try! realm.write {
            person.name = "Jane Doe"
        }
    }
}

答案 1 :(得分:0)

用'add'和'create'添加之间应该没有任何区别。您还更改了一件事情,就是在哪里进行交易(在城市迭代之前或迭代的每个循环之前)进行交易的地方。每个循环都是正确的方法,因此其他写入事务不会等待插入大数据。崩溃仍然很有趣,看来后台优先级队列决定在事务中间分配另一个线程,从而导致崩溃,我认为这永远不会发生。