领域 Swift 异步写入方法

huangapple go评论57阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年5月29日 16:50:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355893.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定