关于在境界数据库事务
这是我Realm
对象:关于在境界数据库事务
class AchievementDate : Object {
dynamic var date: Date = Date()
dynamic var apple: Int = Int(0)
func save() {
do {
let realm = try Realm()
try realm.write {
realm.add(self)
}
} catch let error as NSError {
fatalError(error.localizedDescription)
}
}
}
我改变视图控制器的viewDidLoad()
方法苹果公司的价值,因为你可以看到:
override func viewDidLoad() {
super.viewDidLoad()
achievementDate.apple = 2
achievementDate.save()
}
然后我更新了苹果的价值时,用户点击屏幕上的暂停按钮,如下所示:
@IBAction func pausedButtonTapped(_ sender: UIButton) {
achievementDate.apple += 1
achievementDate.save()
}
Xcode成功运行它,但是当我点击暂停按钮时,应用程序崩溃。在控制台,它说:
***终止应用程序由于未捕获的异常“RLMException”,原因:“试图修改对象的写事务之外 - 先请一个RLMRealm实例 beginWriteTransaction”
我对此很困惑,顺便说一句,交易意味着什么?非常感谢。
写入事务用于将Realm中对象的修改分组为单个工作单元。 Managed Realm对象只能在写入事务中修改。写入交易的范围是您传递给Realm.write(_:)
的呼叫的块。对write
的调用开始写入事务,主体在事务处于活动状态时执行,并且当该块返回写入事务被提交并且更改持久化到Realm文件时。
您还没有分享如何初始化achievementDate
,但基于您看到的是一个AchievementDate
实例是一个托管对象(即,它已创建,然后添加到一个领域,或者它是从一个领域加载的)。作为例外说明,您只能修改写入事务中的托管对象。您可以扩大写入事务的范围以包含修改受管理对象,也可以完全避免修改受管理对象(通过将主键添加到模型类中,并使用Realm.create(_:value:update:)
或Realm.add(_:update:)
和update: true
来更新具有给定主键值的现有对象)。
首先,你需要定义一个主键如果要更新模型:
class AchievementDate: Object {
dynamic var id = 0
dynamic var date:Date = Date()
dynamic var apple:Int = Int(0)
override static func primaryKey() -> String? {
return "id"
}
}
然后更新与示范:
static func save(achievementDate:AchievementDate) {
let realm = try! Realm()
try! realm.write {
realm.add(achievementDate, update: true)
}
}
或者,如果你不不想要主键,并且已经从Realm中检索模型,则可以像这样更新模型:
let realm = try! Realm()
try! realm.write {
achievementDate.apple = 2
}
您不需要定义主键来更新对象。您可以通过任何支持的查询检索对象的引用,然后在写入事务中修改其属性。 – bdash
@bdash如果我定义一个主键来更新对象,我能理解主键实际上是这个对象在内存中的引用吗?然后检索并更新 – Nan
主键(如果声明的话)是唯一标识给定对象的对象上的属性。Realm提供了一些便利函数,可用于声明主键的类(['Realm.object(ofType:forPrimaryKey:)'](https://realm.io/docs/swift/latest/api/Classes/Realm .html#/ s:FC10RealmSwift5Realm6objectu0_RxCS_6ObjectrFT6ofTypeMx13forPrimaryKeyq__GSqx_)和'Realm.create(_:value:update:)'/'Realm.add(_:update:)'''update':''。 – bdash
我通过声明一个变量来初始化对象:var achievementDate = AchievementDate()然后将它传递给View Controller。 – Nan
顺便说一句,如何扩大写交易的范围以包含修改,如何解决这个问题?提前致谢。 – Nan
这意味着它作为一个非托管对象开始生活,但是在您第一次调用'realm.add(self,update:true)'(在'viewDidLoad()'内)时就会被管理。要扩大写入事务的范围,您需要将调用从'save()'函数移出'Realm.write(_ :)'。 – bdash