Удаление объектов Realm в фоновом потоке блокирует основной поток - PullRequest
0 голосов
/ 09 января 2019

У меня возникают зависания в главном потоке после удаления 10 000 объектов из 500 000 в фоновом потоке. Однако вставки не вызывают этой проблемы.

Триггер - это наблюдатель результатов в главном потоке.

Это ошибка в Realm или я что-то упустил?

Вот пример, который производит упомянутое поведение:

AppDelegate

    var realm: Realm!
    var token: NotificationToken?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        realm = try! Realm()

        token = realm.objects(Item.self).observe { change in
            switch change {

            case let .update(_, deletions, insertions, modifications):
                print("deletions: \(deletions.count)")
                print("insertions: \(insertions.count)")
                print("modifications: \(modifications.count)")

            default:
                break
            }
        }

//      addItemsAsync(count: 600000)
        deleteItemsAsync(count: 10000)

        return true
    }

Добавление предметов

func addItemsAsync(count: Int) {
    DispatchQueue.global().async {
        autoreleasepool {
            let realm = try! Realm()

            try! realm.write {
                for i in 0..<count {
                    realm.create(Item.self, value: ["id": i])
                }
            }
        }
    }
}

Удаление элементов

func deleteItemsAsync(count: Int) {
    DispatchQueue.global().async {
        autoreleasepool {
            let realm = try! Realm()

            let itemsToDelete = realm.objects(Item.self).filter("id < \(count)")

            try! realm.write {
                realm.delete(itemsToDelete)
            }
        }
    }
}

Пункт

class Item: Object {
    @objc dynamic var id = 0
}

Я также заметил, что, в отличие от вставок, удаление такого рода не просто уведомляет наблюдателя с 10 000 удалений, но вместо этого я получаю это здесь, когда результаты обновляются в главном потоке:

deletions: 20000
insertions: 10000
modifications: 0

Это, очевидно, из-за повторного заказа. Но я ожидал, что Realm обновит результаты в фоновом режиме, а затем просто поменяет их в главном потоке (особенно это касается дорогостоящих операций).

1 Ответ

0 голосов
/ 09 января 2019

Область не потокобезопасна. Если вы хотите использовать в другом потоке, вы можете использовать ThreadSafeReference.

...