我有一个核心数据模型,实体“Day”包含零个或多个“Workout”。日实体具有许多属性,这些属性通过对所有锻炼进行求和来计算。例如,totalKM将所有锻炼的km属性值相加。
我无法让它发挥作用。
我可以通过覆盖值(forKey)方法来显示总计:
public override func value(forKey key: String) -> Any? {
if(key == "swimSeconds"){
var swimSeconds: Int64 = 0
if let array = workouts?.allObjects{
for w in array{
let workout: Workout = w as! Workout
if (workout.sport == Workout.SPORT.Swim.rawValue){
swimSeconds += workout.seconds
}
}
}
return swimSeconds
}else{
return super.value(forKey: key)
}
}
然而,这意味着如果基础锻炼被更改,则不会反映在日实体中显示的总值中。此外,感觉这不是正确的事情 - 我不应该覆盖这种方法。
我尝试使用Xcode创建NSManagedObject子类,但是它创建了一个包含所有@NSManaged变量的扩展,但这只会产生大量错误“Extensions可能不包含存储的属性”,这只能通过删除@NSManaged来解决。
我尝试创建自己的Extension to Day并拥有一个只有getter的属性:
var totalSwimSeconds: Int64{
get{
var swimSeconds: Int64 = 0
if let array = workouts?.allObjects{
for w in array{
let workout: Workout = w as! Workout
if (workout.sport == Workout.SPORT.Swim.rawValue){
swimSeconds += workout.seconds
}
}
}
return swimSeconds
}
}
此方法产生运行时错误: 实体日不是密钥“totalSwimSeconds”
的密钥值编码兼容我在线搜索是否可以找到这样的示例,但所有示例都只是在给定实体中组合属性的简单情况(例如,来自DOB的年龄,名字和姓氏的全名)更复杂的计算,查看其他实体中包含的属性。
如何在核心数据中创建计算属性,该属性将从基础实体计算并在更新时进行更新?
[我在Swift 4中使用Xcode 9]
答案 0 :(得分:3)
在Swift 4中添加属性@objc
和dynamic
以使计算属性键值编码符合。
@objc dynamic var totalSwimSeconds: Int64 { ...
编辑:
观察workouts
keyPathsForValuesAffectingValue
属性覆盖Day
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
switch key {
case "totalSwimSeconds": return Set(["workouts"])
default: return super.keyPathsForValuesAffectingValue(forKey:key)
}
}