ios - 在后台线程上删除 Realm 对象会阻塞主线程

标签 ios swift multithreading realm grand-central-dispatch

在后台线程上删除 500,000 个对象中的 10,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 在后台更新结果,然后简单地在主线程上交换它(尤其是这类昂贵的操作)。

最佳答案

Realm 不是线程安全的。如果你想在不同的线程中使用,你可以使用ThreadSafeReference。

关于ios - 在后台线程上删除 Realm 对象会阻塞主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54102963/

相关文章:

swift - 我如何在 Swift 中比较两个字典?

ios - 使用 CAShapeLayer 对蒙版部分的透明度进行动画处理

java - google volley 单例真的线程安全吗?

iphone - 如何设置自定义规则,例如 GameCenter 寻找比赛的难度级别

ios - CollectionView 组合布局中的部分标题 z 索引 - iOS 13

ios - NSKeyValueObservingOptions 快速错误

java - 如何将简单的 Java Echo Server 改为多线程?

iOS:滑动手势在同一 Controller 内加载不同的数据

ios - 在 iOS 开发门户中创建配置文件时未显示推送证书

java - 异步 DoInBackground 在 Listview 下崩溃