LoginSignup
0
0

More than 1 year has passed since last update.

Realm objectの取り回し方法について考える

Last updated at Posted at 2021-12-24

(なぜか限定公開でPublicにしてなかったので今頃公開。基本的な考え方は今でも通じるはず)

なぜ考える必要があるのか

VOを何にするか

Realm object(DAO)をVOに変換すれば安全に取り回すことができるので、VOをどうするかを考えます。

1. struct

定義例

protocol PersonType {
    var name: String { get }
    var age: Int { get }
}

@objcMembers
class Person: Object, PersonType {
    dynamic var name = ""
    dynamic var age = 0
}

struct PersonObject: PersonType {
    let name: String
    let age: Int
}
  • Realm objectとstructの相互変換する方法が必要
  • Realm objectとstructで同一の定義が必要で冗長

2. Unmanaged Realm objectをprotocolで返す

定義例

protocol PersonType {
    var name: String { get }
    var age: Int { get }
}

@objcMembers
class Person: Object, PersonType {
    dynamic var name = ""
    dynamic var age = 0
}
  • Managed Realm objectをUnmanaged Realm objectにする方法が必要
  • setterを含むProtocolも返せばDTOとすることも可能

相互変換の方法

方法 デメリット
変換コードを自前で書く 変換コードのメンテナンスコストが高く、ミスが入る可能性も高い
Codable経由で変換 Decode/Encode分の処理コスト増、Codableに準拠するためのコードが必要
Extra/Realmdetached() 実装はディープコピー。ただ、ユニットテストが書かれていないので不安
EVReflectable/Realm経由で変換 fetchしたオブジェクトは正常にリフレクションできなかったので除外
EasyRealmunmanaged() 実装はディープコピー。RealmSwiftのバージョンがEasyRealm.podspecに依存してしまう

有力候補

EasyRealm

let trainer = Trainer()
let pokedex = Pokedex()
trainer.pokemons.append(HelpPokemon.generateCapturedRandomPokemon())
trainer.pokedex = pokedex

trainer.pokemons.forEach {
  $0.specialBoost.value = 42
}

try! trainer.er.save(update: true)
let managed = trainer.er.managed!
XCTAssertTrue(managed.er.isManaged)
XCTAssertTrue(managed.pokedex!.er.isManaged)
XCTAssertFalse(managed.pokemons.isEmpty)
managed.pokemons.forEach {
  XCTAssertTrue($0.er.isManaged)
    XCTAssertEqual($0.specialBoost.value!, 42)
}

let unmanaged = managed.er.unmanaged
XCTAssertFalse(unmanaged.er.isManaged)
XCTAssertFalse(unmanaged.pokedex!.er.isManaged)
XCTAssertFalse(unmanaged.pokemons.isEmpty)
unmanaged.pokemons.forEach {
  XCTAssertFalse($0.er.isManaged)
  XCTAssertEqual($0.specialBoost.value!, 42)
}

まとめ

  • 公式がサポートするまで何らかの代替方法で乗り切るしかありません。
  • どの方法も変換コストがかかるのでパフォーマンスとのトレードオフになります。パフォーマンスを求めたい部分はRealm objectやResults等を直接扱って気をつけて運用するしかないのかなと思います。
0
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
0
0