简体   繁体   中英

Deleting Realm objects on a background thread blocks the main thread

I'm experiencing freezes on the main thread after deleting 10,000 objects out of 500,000 on a background thread. Insertions, however, don't cause this issue.

The trigger is the Results observer on the main thread.

Is this a bug in Realm or am I missing something?

Here is an example that produces the mentioned behavior:

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
    }

Adding items

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

Deleting items

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

Item

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

I also noticed that, unlike insertions, a deletion of this sort doesn't simply notify the observer with 10,000 deletions, but instead I get this here once the results are updated on the main thread:

deletions: 20000
insertions: 10000
modifications: 0

This is obviously due to re-ordering. But I would have expected that Realm updates the results in the background and then simply swaps it on the main thread (especially these kind of expensive operations).

Realm not thread safe. If you want to use in different thread you can use ThreadSafeReference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM