🤖

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

2021/12/29に公開

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以外にはならないはず
}

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

Discussion