1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RealmのcreateOrUpdateはオンメモリ側のプロパティに値をセットしなければその項目はnilになる

Last updated at Posted at 2021-08-23

はじめに

タイトルを悩んだが適切なタイトルの表現が難しい。

RealmSwiftのcreateOrUpdateことcreate(_:value:update:)メソッドにおいて、updateパラメータに.modifiedもしくは.allを指定した場合かつプライマリキーを持つオブジェクトを更新する場合にその際の挙動について書いておく(後述するがCore Dataとほぼ同じ挙動だった)。

公式のリファレンスに従ってやや冗長に言い換えると、『主キーを持つオブジェクトによって既存を更新する場合は、新しいオブジェクト自体でプロパティが更新される』といったところかもしれない。

If an object already exists in the Realm with the specified primary key and the update policy is .modified or .all, the existing object will be updated and a reference to that object will be returned.

前提

  • RealmSwift
  • v10.12.0

(おそらくRealmの出た当初からこの挙動は変わっていないのであまり重要ではない)

createOrUpdate実例

nameプロパティにセットしない場合

まずRealm.Objectの説明から

class Person: Object {
    @objc dynamic var id = 0
    @objc dynamic var name: String? // この値をセットしなかったりしてみる

    override static func primaryKey() -> String? {
        #keyPath(Person.id)
    }
}

このPersonのidを1にしたものを作成しnameをp1とする。そしてさらにid: 1を更新し、nameをセットしない。


func createPerson() {
    let realm = try! Realm()

    func debug(_ person: Person) {
        print("---")
        print("person.id:", person.id)
        print("person.name:", person.name ?? "nil")
    }

    do {
        let person = Person()
        person.id = 1
        person.name = "p1"

        try! realm.write {
            realm.create(Person.self, value: person, update: .modified)
        }

        debug(realm.object(ofType: Person.self, forPrimaryKey: 1)!)
    }

    do {
        let person = Person()
        person.id = 1
//            person.name = "p1" // ここでセットしないことでどうなるのかを検証したい

        try! realm.write {
            realm.create(Person.self, value: person, update: .modified)
        }

        debug(realm.object(ofType: Person.self, forPrimaryKey: 1)!)
    }
}

出力は次の通りとなり、新しいPersonによってデータがnameなしに上書きされたのがわかる。

---
person.id: 1
person.name: p1
---
person.id: 1
person.name: nil
  • Person
    • id
      • 1
    • name
      • nil

おわりに

(試せばわかると思うので)上記では細かく書いてないが、リレーションする内容もセットされていなければnameと同じようにnilになる。

関連

Core Dataはどうなるのか

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?