Swift
Realm

【解決】realm.writeでの謎挙動

More than 1 year has passed since last update.

writeは全然関係なくて、filterの使い方が悪かった。

環境

  • RealmSwift 0.97.0
  • Realm 0.97.0
  • Xcode 7.2
  • iOS 8.1のシミュレータ
  • iOS 9.2の実機(iPhone 6s)

ダメなコード

import Foundation
import RealmSwift

final class Record: Object {
  dynamic var id = ""
  dynamic var updatedAt: Double = 0.0

  override static func primaryKey() -> String? {
    return "id"
  }
}

func test() {
  guard let realm = try? Realm() else { return }

  let items = Array(0..<100).map { "\($0)" }

  try! realm.write {
    let timestamp = NSDate().timeIntervalSince1970

    items.forEach { item in
      let record = Record()
      record.id = item
      record.updatedAt = timestamp

      realm.add(record, update: true)
    }

    realm.refresh()

    let results = realm.objects(Record).filter("updatedAt < \(timestamp)")
    print("==========")
    print("\(results.first?.updatedAt < timestamp)") // trueのはず
    print(results.count) // 0以外にはならないはず
  }
}

という感じのコードで、test()を何度か実行してみたところ

==========
false
100
==========
false
100
==========
false
100
==========
true
0
==========
false
100
==========
false
100
==========
true
0
==========
true
0
==========
false
100
==========
true
0

こんな感じでちぐはぐな感じに…。

うーん。なんだろう。

forの中でwriteしてみてもダメだった

final class Record: Object {
  dynamic var id = ""
  dynamic var updatedAt: Double = 0.0

  override static func primaryKey() -> String? {
    return "id"
  }
}

func test() {
  guard let realm = try? Realm() else { return }

  let items = Array(0..<100).map { "\($0)" }

  let timestamp = NSDate().timeIntervalSince1970
  items.forEach { item in
    try! realm.write {
      let record = Record()
      record.id = item
      record.updatedAt = timestamp

      realm.add(record, update: true)
    }
  }

  realm.refresh()

  let results = realm.objects(Record).filter("updatedAt < \(timestamp)")
  print("==========")
  print("\(results.first?.updatedAt < timestamp)") // trueのはず
  print(results.count) // 0以外にはならないはず
}
==========
true
0
==========
true
0
==========
false
100
==========
true
0
==========
true
0
==========
false
100
==========
true
0
==========
true
0
==========
true
0
==========
false
100

動いたコード

func doSomething() {
  guard let realm = try? Realm() else { return }

  let items = Array(0..<100).map { "\($0)" }

  let timestamp = NSDate().timeIntervalSince1970
  items.forEach { item in
    try! realm.write {
      let record = Record()
      record.id = item
      record.updatedAt = timestamp

      realm.add(record, update: true)
    }
  }

  realm.refresh()

  let results = realm.objects(Record).filter("updatedAt < %lf", timestamp)
  print("==========")
  print("\(results.first?.updatedAt < timestamp)") // trueのはず
  print(results.count) // 0以外にはならないはず
}

という感じで、文字列に埋め込むのを辞めたらうまくいった。