替换列表< T>对象在Realm中无法持续存在 [英] Replaced List<T> object not persisting consistently in Realm

查看:54
本文介绍了替换列表< T>对象在Realm中无法持续存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个List<Workout>对象,偶尔需要对其进行排序(例如,如果用户添加了一个无序的锻炼),但是我似乎无法使新的排序后的List<Workout>持久化.我的代码在运行时即起作用(即按排序显示在视图上),但是当我退出ViewController或重新启动应用程序时,什么也没看到.什么都不是由于exercise.workoutDiary.removeAll()的持久性引起的,但是显然对exercise.workoutDiary = sortedWorkoutDiary的后续分配没有持久性.有什么想法吗?

I have a List<Workout> object that occasionally needs to be sorted (e.g., if a user adds a Workout out of order), but I can't seem to get the new sorted List<Workout> to persist. My code works the moment it runs (i.e., it shows up on the view as sorted), but when I exit the ViewController or restart the app, I see nothing. The nothing is due to the exercise.workoutDiary.removeAll() persisting, but apparently the subsequent assignment to the exercise.workoutDiary = sortedWorkoutDiary is not persisting. Any ideas why?

其他一切都很好.典型的recordWorkout()情况在没有输入任何乱序的情况下起作用.因此,除了覆盖已排序的List之外,持久化几乎在所有情况下都有效.

Everything else works just fine. The typical recordWorkout() case works assuming nothing is entered out of order. So the persisting is working in nearly all cases except for this overwrite of the sorted List.

更新发生在这里:

struct ExerciseDetailViewModel {

    private let exercise: Exercise!

    func recordWorkout(newWorkout: Workout) {
        let lastWorkout = exercise.workoutDiary.last // grab the last workout for later comparison

        let realm = try! Realm()
        try! realm.write {
            exercise.workoutDiary.append(newWorkout) // write the workout no matter what
        }

        if let secondToLastWorkout = lastWorkout { // only bother checking out of order if there is a last workout...
            if newWorkout.date < secondToLastWorkout.date { // ...and now look to see if they are out of order
                let sortedWorkoutDiary = exercise.sortedWorkouts
                try! realm.write {
                    exercise.workoutDiary.removeAll()
                    exercise.workoutDiary = sortedWorkoutDiary
                }
            }
        }
    }
}

final class Exercise: Object {

    var workoutDiary = List<Workout>()
    var sortedWorkouts: List<Workout> {
        return List(workoutDiary.sorted("date"))
    }
}

final class Workout: Object {

    dynamic var date = NSDate()
    var sets = List<WorkSet>()
}

Realm Swift中的

推荐答案

List<T>属性必须在适当位置进行突变,而不是分配给它们. Swift运行时不为Realm提供任何方式来拦截对通用类型的属性的分配.相反,您应该使用 appendContentsOf(_:) 之类的方法进行突变List<T>:

List<T> properties in Realm Swift must be mutated in place, not assigned to. The Swift runtime does not provide any way for Realm to intercept assignments to properties of generic types. Instead, you should use methods like appendContentsOf(_:) to mutate the List<T>:

exercise.workoutDiary.removeAll()
exercise.workoutDiary.appendContentsOf(sortedWorkoutDiary)

对通用类型的属性进行赋值的限制就是为什么Realm Swift文档建议您声明使用let而不是var 这样的属性.这将使Swift编译器能够捕获此类错误.

This limitation on assignment to properties of generic types is why the Realm Swift documentation recommends that you declare such properties using let rather than var. This will allow the Swift compiler to catch these sorts of mistakes.

还有一点需要注意:对于您的sortedWorkouts计算属性,最好返回Results<Workout>,以避免分配和填充中间List<Workout>.

One further note: for your sortedWorkouts computed property, it'd be preferable for it to return Results<Workout> instead to avoid allocating and populating an intermediate List<Workout>.

这篇关于替换列表&lt; T&gt;对象在Realm中无法持续存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆