在 Core Data 中创建计算属性

Ste*_*ord 6 xcode core-data swift

我有一个连接到 Storyboard GUI 的核心数据模型。(Xcode 9 和 SWIFT 4)我现在想添加一个源自其他两个属性的属性。我有一个名为 Workout 的实体,它的两个属性“rpe”和“秒”组合起来创建一个新属性“rpeTSS”。我已将“repTSS”声明为我的核心数据模型中的属性。我把它设置为瞬态。

我尝试使用编辑器菜单下的“make NSManagedObject subclass...”选项,但这似乎会生成有错误的文件。我尝试对生成的 Workout 类进行子类化,但不知道如何将其绑定到 GUI。

然后我对 Workout 进行了扩展:

extension Workout{

    public override func value(forKey key: String) -> Any? {
        if key == "rpeTSS"{
            return (100/49)*rpe*rpe*Double(seconds)/3600
        }else{return super.value(forKey: key)}
    }
}
Run Code Online (Sandbox Code Playgroud)

老实说,这“感觉”不对。无论如何,它(有点)有效。我现在得到了 rpeTSS 的正确值,它显示在我的 GUI 中。但是,如果我对 rpe 和/或秒进行更改,GUI 不会更新。

我猜上面的方法有点破解,因此绕过了更新 GUI 的各种消息传递。

在核心数据中添加派生属性的正确方法是什么?我试图以一种方式实现这一点,这意味着如果我向数据模型添加任何内容,我不必重新编写派生属性的代码。

Ste*_*ord 3

我想出的最终解决方案看起来和感觉都是正确的。它需要重写 keyPathsForValuesAffectingValue(forKey:) 如下:

extension Workout{

    @objc dynamic var rpeTSS: Double{
        return (100/49)*rpe*rpe*Double(seconds)/3600
    }

    override public class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String>{
        let keyPaths = super.keyPathsForValuesAffectingValue(forKey: key)
        switch key {
        case "rpeTSS":
            return keyPaths.union(Set(["seconds","rpe"]))
        default:
            return keyPaths
        }
}
Run Code Online (Sandbox Code Playgroud)