【问题标题】:Write to Realm in a loop循环写入领域
【发布时间】:2019-02-17 00:01:53
【问题描述】:

我正在通过这个对象类在 Realm 中存储锻炼信息:

class Workout: Object {

    @objc dynamic var date: Date?
    @objc dynamic var name: String?
    @objc dynamic var exercise: String?
    @objc dynamic var sets = 0
    @objc dynamic var reps = 0
    @objc dynamic var kg: Double = 0.0
    @objc dynamic var notes: String?
}

我将数据存储为一个数组,我想将其写入 Realm,如下所示:

var workoutName = ""
var exercises = [String]()
var sets = [Int]()
var reps = [Int]()
var kg = [Double]()
var notes = [String]()

@IBAction func saveWorkoutButton(_ sender: Any) {

    let realm = try! Realm()

    print(Realm.Configuration.defaultConfiguration.fileURL!)

    let currenDate = Date() // Get the current date

    let myWorkout = Workout()
    myWorkout.date = currenDate
    myWorkout.name = workoutName

    for i in 0 ..< exercises.count {
        myWorkout.exercise = exercises[i]
        myWorkout.sets = sets[i]
        myWorkout.reps = reps[i]
        myWorkout.kg = kg[i]
        myWorkout.notes = notes[i]

        realm.add(myWorkout)
    }

    try! realm.write {
        realm.add(myWorkout)
    }
}

这种情况下的问题是,在运行realm.write ... 时,它只添加了for i in 0 函数的最后一个值。我尝试将realm.write 函数放在for i in 0 循环中,但随后它崩溃了。每个数组都包含相等数量的对象。有什么想法吗?

【问题讨论】:

  • 为什么你有 5 个并行数组都包含相同数据的片段?这非常容易出错。你最终会犯一个导致数组不同步的错误,例如忘记添加kg
  • @Alexander 如果任何一个值为空,它甚至不会保存它,所以不用担心。
  • 这不足以保护您免受这种设计可能发生的多种不可避免的错误。例如,如果您添加到setsrepskgnotes,但忘记添加到exercises 怎么办?你会有一个不完整的数据集,它会默默地失败。你应该在你收集这些数据的地方创建你的 workout 对象。
  • @Alexander 好吧,你有什么建议给我,而不是仅仅批评我选择这样做的方式吗?
  • 好吧,您已经发现了并行数组的问题,因为您正在将它们转换为连贯的对象(Workout 类型)。你只需要早一点做这个过程,从一开始就创建Workout对象,完全删除这个“所有数据被分成许多并行数组”部分。

标签: ios arrays swift realm


【解决方案1】:

你可以试试这个代码:

var myWorkouts:[Workout] = []
for i in 0 ..< exercises.count {
    let myWorkout = Workout()
    myWorkout.date = currenDate
    myWorkout.name = workoutName
    myWorkout.exercise = exercises[i]
    myWorkout.sets = sets[i]
    myWorkout.reps = reps[i]
    myWorkout.kg = kg[i]
    myWorkout.notes = notes[i]
    myWorkouts.append(myWorkout)
}

try! realm.write {
    realm.add(myWorkouts)
}

如果可能,您应该只 addwrite 一次以优化性能。 希望这会有所帮助。

【讨论】:

  • 谢谢!我应该做try! realm.write { 还是应该添加一些错误处理(如果有任何错误)?那怎么办?
  • @qtngo 好的开始,但我建议避免写for i in 0..&lt;a.count。太容易误写for i in 0...a.count,导致bug。另外,这甚至不适用于数组切片。相反,请使用for i in a.indices
  • @Trinity:在 Realm 文档中,他们总是使用 try!。所以我认为这是一个好方法。根据我使用 Realm 的经验,我对此没有任何问题。此外,如果应用程序由于某种原因突然出现写入磁盘的问题,最好显式崩溃,然后继续处理错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
相关资源
最近更新 更多