Я использовал расширение для добавления вычисляемых свойств в базу данных CoreData. Я хотел бы использовать NSSortDescriptor с FetchRequest для фильтрации и сортировки информации CoreData на основе одного из этих вычисляемых свойств. Код без проблем компилируется и работает нормально при сортировке на основе собственного атрибута CoreData, но код падает во время выполнения при попытке применить NSSortDescriptor на основе вычисляемого поля.
Ниже приведен упрощенный фрагмент кода, взятого из моего файла "GameLog + CoreDataProperties.swift", где вычисленное свойство определено в расширении. Это компилируется и выполняется правильно:
import Foundation
import CoreData
extension GameLog {
@nonobjc public class func fetchRequest() -> NSFetchRequest<GameLog> {
return NSFetchRequest<GameLog>(entityName: "GameLog")
}
@NSManaged public var date: Date?
@NSManaged public var id: UUID?
@NSManaged public var totalPoints: Int32
@NSManaged public var numberOfGames: Int32
/* Calculated fields for game statistics */
@objc dynamic var scorePerGame: Double {
return Double(totalPoints) / Double(numberOfGames)
}
var wrappedDate: Date {
date ?? Date()
}
var wrappedID: UUID {
id ?? UUID()
}
var wrappedPoints: Int32 {
totalPoints
}
var wrappedNumberOfGames: Int32 {
numberOfGames
}
}
Ниже приведен фрагмент кода, в котором я установил NSPredicate и NSSortDescriptor, которые будут использоваться для фильтрации и сортировки данных. Это также компилируется и работает правильно (после того, как я пометил вычисляемое свойство как "@ obj c dynamici c"):
// Set how the results will be filtered and sorted
predicate = NSPredicate(format: "date >= %@", Calendar.current.date(byAdding: .day, value: -7, to: Date())! as NSDate)
switch self.chosenStats {
case 0: // Total points
sortDescriptor = NSSortDescriptor(keyPath: \GameLog.totalPoints, ascending: false)
case 1: // Games
sortDescriptor = NSSortDescriptor(keyPath: \GameLog.numberOfGames, ascending: false)
default: // Points per game
sortDescriptor = NSSortDescriptor(keyPath: \GameLog.scorePerGame, ascending: false)
}
Однако, когда приложение выполняется и фильтр сортировки применяется, он отлично работает в первых двух случаях (где сортировка основана на собственном атрибуте CoreData), но в третьем случае (с использованием NSSortDescriptor на основе вычисляемого свойства) происходит сбой приложения с ужасной ошибкой «Thread 1: signal SIGABRT».
Ниже приведен код, в котором я вызываю представление, используемое для фильтрации и сортировки:
FilteredGameView(filterCriteria: self.predicate, sortCriteria: [self.sortDescriptor])
Это код (упрощенный) для отображения отфильтрованных и отсортированных игр. Как отмечалось выше, это прекрасно работает при сортировке по собственным атрибутам CoreData (случай 0 и 1), но не по вычисляемому свойству (случай 2).
import SwiftUI
struct FilteredHOFView: View {
var filteredGames: FetchRequest<GameLog>
@Environment(\.managedObjectContext) var moc
init(
filterCriteria: NSPredicate,
sortCriteria: [NSSortDescriptor]
) {
self.filteredGames = FetchRequest(
entity: GameLog.entity(),
sortDescriptors: sortCriteria,
predicate: filterCriteria
)
}
var body: some View {
List {
ForEach(filteredGames.wrappedValue, id: \.self) { game in
HStack {
Text("Show stats here")
}
}
}
}
}
Есть мысли о том, в чем проблема? Есть ли что-то особенное, что мне нужно сделать при применении маркера @ obj c?