有没有办法在 Core Data 中使用带有参数的计算 属性 ?

Is there a way to use a computed property with a parameter in Core Data?

这可能是一个奇怪的问题,因为我不完全理解 transient 和新的派生属性在 Core Data 中是如何工作的。 所以想象一下我有一个 RegularClass 实体,它存储随时间重复的任何 class。例如,class 可以每三天或每一周重复一次。这是它在数据模型中的样子:

RegularClass 属于 Schedule 实体,后者又属于 Course 实体)

现在,如果我们的 class 每三天重复一次,我们将数字 3 存储在 frequency 属性 中,并将字符串 "days" 存储在 unit 属性,然后在 Swift 中转换为枚举。每个RegularClass所属的Schedule有一个startDate属性。

为了检查 class 是否在给定日期发生,我没有比计算 startDate 和给定日期之间指定 unit 的差异更好的方法了,然后在差值和频率之间取余数,如果它是 0,那么它就是 class 可能发生的日期。

var differenceComponent: Calendar.Component {
    switch unitType {
    case .weeks:
        return .weekOfYear
    case .days:
        return .day
    }
}

func getDifferenceFromDateComponents(_ dateComponents: DateComponents) -> Int? {
    switch unitType {
    case .weeks:
        return dateComponents.weekOfYear
    case .days:
        return dateComponents.day
    }
}

func dateIsInActiveState(_ date: Date) -> Bool {
    if let startDate = schedule?.startDate {
        let comps = Calendar.current.dateComponents([differenceComponent], from: startDate, to: date)
        if let difference = getDifferenceFromDateComponents(comps) {
            let remainder = Int64(difference) % frequency // that is the key!
            return remainder == 0
        }
    }
    return false
}

func containsDate(_ date: Date) -> Bool {
    if dateIsInActiveState(date) {
        if unitType == .days {
            return true
        }

        let weekday = Calendar.current.component(.weekday, from: date)
        return (weekdays?.allObjects as? [Weekday])?.contains(where: { [=11=].number == weekday }) ?? false
    }

    return false
}

现在,问题是这段代码非常适合我已经从获取请求中获得的课程。但是有没有一种方法可以在 NSPredicate 中传递日期参数来在请求发生时进行计算?或者我是否必须获取所有课程然后手动过滤掉它们?

要解决此问题,您可以将数据存储为标量类型,然后在谓词中进行简单的算术运算。而不是日期,使用具有从零开始的天数的整数(或这些计算所需的任何最小时间单位)。将您的重复周期存储为天数。

然后您可以在谓词中使用计算 ((searchDate - startDate) mod repeatCycle) == 0 来查找匹配项 类。

正如您所建议的,针对不同的搜索案例对数据进行非规范化处理可能是明智的。