realm - 如何在 SwiftUI 表单中使用 Realm
问题描述
由于未捕获的异常“RLMException”而终止应用程序,原因:“尝试在写入事务之外修改对象 - 首先在 RLMRealm 实例上调用 beginWriteTransaction。”
对托管对象的所有更改(添加、修改和删除)都必须在写入事务中完成。例如,
// Update an object with a transaction
try! realm.write {
author.name = "Thomas Pynchon"
}
我可以使 Realm 子类符合 ObservableObject。但是,我看不到如何在 SwiftUI 中使领域属性可更新。下面的领域属性示例。
@objc dynamic var myName: String = "Adam"
Realm 基于 @objc 动态变量自动设置模式。我看不到在领域属性上获取 @Published 的方法。SwiftUI 将呈现一个 TextField,但在编辑该值时会崩溃。
TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.stdQty, formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
有没有办法将 SwiftUI 状态更改包装在 Realm 写入事务中?
解决方案
考虑 Realm 属性,stdQty 如下所示。它只能在写入事务中更改。
import RealmSwift
import Combine
class ShoppingItems: Object, ObservableObject
let objectWillChange = PassthroughSubject<Void, Never>()
@objc dynamic var stdQty: Double = 1
如果没有原始问题中的错误,您将无法绑定 stdQty。但是,您可以创建一个可以绑定的计算变量。
var formQty: Double {
get {
return stdQty
}
set {
objectWillChange.send()
if let sr = self.realm {
try! sr.write {
stdQty = newValue
}
}
}
}
绑定计算的变量可以正常工作。
TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.formQty, formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
答案限制:objectWillChange 仅由计算变量触发。表格的变化反映在表格中。领域中的更改尚未触发组合 objectWillChange。
推荐阅读
- python - OSX中的Cython openMP ...没有构建
- javascript - 从 JavaScript/jQuery 中的 html 输入框中删除重复条目
- ios - 导航栏的圆角和阴影
- javascript - 如何为生产部署 Ember CLI 快速启动应用程序?
- php - Laravel 向 mysql 中插入多个数组
- c# - 为什么 .NET Core 中 Enumerable.Zip() 的 2 参数重载但 .NET Standard 中没有?
- java - 带有 swagger2 的 Java Spring 未启动服务器
- azure - Azure 表存储中插入的新项目不会立即可用
- node.js - discord.js 将参数数据存储在一个名为 + guild id 的文件中
- ember.js - 如何在不经过 JSON 解析的情况下从后端获取文件