値の更新(update)

慣れると大した事ないけど、はじめは戸惑うこの仕様。
動作環境
環境 | バージョン |
---|---|
Xcode | 9.4.1 |
iOS | 11.4 |
swift | 4.1.2 |
Realm | 3.1.1 |
SQLのupdate文との違い
ついついRDB感覚で、値を更新(update)となると、
- 書き換える値をセット(set句)
- 書き換えるレコードの条件をセット(where句)
と考えてしまうのですが、若干感覚が異なります。 考え方の大筋は問題ないですが。
ついやってしまう過ち
updateする際は、まずテーブルにデータを探しに行きます。
// 更新対象のデータを取得
let item: Item = itemInteractor.selectById(id: itemId)
ここで使ってるselectById()
はこんな定義で、1件のみ取得します。
func selectById(itemId iId: Int) -> Item()? {
let predicate: NSPredicate = NSPredicate(format: "itemId = %d", iId)
let results: Results<Item> = realm.objects(Item.self).filter(predicate)
if results > 0 {
return results[0]
}
return nil
画面でユーザが値を変更したら、取得データを書き換え。
item.name = itemName
しかし!
これをやると以下のようなエラーが出力される。
Attempting to modify object outside of a write transaction
Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
トランザクション外で値書き換えんじゃねぇよと怒られます。
実際の変更方法
ということなので、トランザクション内で書き換えてあげましょう。
let realm: Realm = try! Realm()
// 書き込みトランザクション開始
try! realm.write {
item.name = itemName
}
これでOKです。
一旦、realmに追加、保存したデータはマネージドオブジェクトとなり、Realmの監視対象となってしまうため、トランザクション外で書き換えを行うと、exceptionが発生します。
[amazon_link asins=’4774188484′ template=’custom’ store=’takayuki57101-22′ marketplace=’JP’ link_id=’41b59a0e-a3c7-11e8-8153-15a7dfbcc5b7′]