英文:
Realm Swfit Async Write Method
问题
我刚开始接触Swift的并发编程,尤其是Realm Swift。我有两个示例代码,我认为它们是相同的,但它们不起作用。
下面是不起作用的示例代码:
var localRealm: Realm {
    get {
        return try! Realm()
    }
}
fileprivate func testAsyncRealm() {
    self.localRealm.beginAsyncWrite {
        self.localRealm.create(SwiftStringObject.self, value: ["string2"])
        self.localRealm.commitAsyncWrite(allowGrouping: true) { error in
            print(error)
        }
    }
}
这段代码会引发异常:Terminating app due to uncaught exception 'RLMException', reason: Can only add, remove, or create objects in a Realm in a write transaction - call beginWriteTransaction on an RLMRealm instance first.
然而,下面的代码将可以正常工作,没有任何问题:
fileprivate func testAsyncRealm() {
    let realm = try! Realm()
    realm.beginAsyncWrite {
        realm.create(SwiftStringObject.self, value: ["string2"])
        realm.commitAsyncWrite(allowGrouping: true) { error in
            print(error)
        }
    }
}
我在这里漏掉了什么?谢谢...
Realm 版本:10.40.0
英文:
I am new with swift concurrency especially Realm Swift. I have 2 sample codes where i think are the same, but it won't work
Below is the example of not working code
var localRealm: Realm {
    get {
        return try! Realm()
    }
}
fileprivate func testAsyncRealm() {
    self.localRealm.beginAsyncWrite {
        self.localRealm.create(SwiftStringObject.self, value: ["string2"])
        self.localRealm.commitAsyncWrite(allowGrouping: true) { error in
            print(error)
        }
    }
}
This code will throw exception
Terminating app due to uncaught exception 'RLMException', reason: Can only add, remove, or create objects in a Realm in a write transaction - call beginWriteTransaction on an RLMRealm instance first.
However, below code will work without any problem
fileprivate func testAsyncRealm() {
    let realm = try! Realm()
    realm.beginAsyncWrite {
        realm.create(SwiftStringObject.self, value: ["string2"])
        realm.commitAsyncWrite(allowGrouping: true) { error in
            print(error)
        }
    }
}
What am I missing here? Thanks...
Realm Version: 10.40.0
答案1
得分: 1
这只是一个理论,但适用于这个问题。
当一个 Realm 对象开始一个异步写事务时,似乎会在该 Realm 上设置一个标志 isPerformingAsynchronousWriteOperations,以指示它正在进行异步写操作。例如:
var realm = try! Realm()
realm.beginAsyncWrite {
   let isWrite = realm.isPerformingAsynchronousWriteOperations
   print("is write? \(isWrite)") //输出 true
}
然而,在你的代码中(缩写版本):
var localRealm: Realm {
    get {
        return try! Realm()
    }
}
fileprivate func testAsyncRealm() {
    self.localRealm.beginAsyncWrite {
       let isWrite = self.localRealm.isPerformingAsynchronousWriteOperations
       print("is write? \(isWrite)") //输出 false
    }
}
输出是 false,表示该标志未设置,因此 Realm 不认为它处于异步写状态。
我将提出这种行为是因为每次通过 self.localRealm 访问该变量时,都会重新初始化 Realm,该标志为 false。
简单的解决方案是在不重新初始化的情况下使用相同的 Realm 实例:
fileprivate func doAsyncWrite() {
   var realm = self.localRealm  //获取一个 Realm 实例
   realm.beginAsyncWrite { //使用相同的 Realm 进行写入,这会设置标志
      let isWrite = realm.isPerformingAsynchronousWriteOperations
      print("is write? \(isWrite)") //返回 true
   }
}
通过这种更改,问题中的代码将正确工作。
英文:
This is just a theory but fits the issue
When a realm object begins an async write transaction, it appears a flag is set on that realm isPerformingAsynchronousWriteOperations to indicate it's in an async write. For example
var realm = try! Realm()
        
realm.beginAsyncWrite {
   let isWrite = realm.isPerformingAsynchronousWriteOperations
   print("is write? \(isWrite)") //outputs true
}
However, in your code (abbreviated)
var localRealm: Realm {
    get {
        return try! Realm()
    }
}
fileprivate func testAsyncRealm() {
    self.localRealm.beginAsyncWrite {
       let isWrite = self.localRealm.isPerformingAsynchronousWriteOperations
       print("is write? \(isWrite)") //outputs false
    }
}
the output is false - indicating that the flag was not set so Realm doesn't think its in an asynch write.
I'll propose the behavior is because each time the var is accessed via self.localRealm, it re-initializes Realm, with that flag being false.
The simple solution is to work with the same instance of Realm without re-initializing it
fileprivate func doAsyncWrite() {
   var realm = self.localRealm  //gets a realm instance
        
   realm.beginAsyncWrite { //use that same realm to write, which sets the flag
      let isWrite = realm.isPerformingAsynchronousWriteOperations
      print("is write? \(isWrite)") //returns true
   }
}
With that change, the code in the question works correctly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论