如何按测量基础类排序FetchedResultsController,以前:保存时核心数据崩溃

时间:2018-04-03 12:33:18

标签: ios swift core-data

将新数据保存到Core Data时,我遇到了一个奇怪的崩溃。结构的相关部分如下:

$rb_token = bin2hex(random_bytes($length));
$oa_token = bin2hex((new OAuthProvider())->generateToken($length, TRUE));
// TRUE = strong "/dev/random will be used for entropy"

CoreData只是一个常量的结构。

我的模型具有addParachute中每个列出项的属性。当我尝试将所有项目添加到Core Data模型时,我遇到以下崩溃:

  

NSManagedObjectContextObjectsDidChangeNotification。 - [NSMeasurement compare:]:使用userInfo(null)发送到实例0x1c04211e0的无法识别的选择器   2018-04-03 08:28:48.533419-0400恢复[1210:643911] ***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [NSMeasurement compare:]:无法识别的选择器发送到实例

如果我拉出任何一项属性,它会保存得很好。它与哪个项目无关。我甚至无法将其缩小到任何特定属性。我有其他实体保存测量,基本相同设置,没有问题。

连连呢?提前谢谢。

编辑:

由于这篇文章,我正在找到崩溃的真正原因: Extremely Odd Crash When saving a transformable NSAttributedString into Core Data

我之前没有找到它,因为它是一个Objective C问题。但是,基本问题是相同的:我的FetchedResultsController因核心数据保存而更新。

在我的View Controller类中,我有以下功能:

struct ParachuteDataController {

let databaseController = DatabaseController()
let context = DatabaseController().getContext()

    func addParachute(newParachute: ParachuteData) {

        let parachute = Parachute(context: context)

        parachute.setValue(newParachute.diameter, forKey: CoreData.diameter)
        parachute.setValue(newParachute.area, forKey: CoreData.area) //Measurement
        parachute.setValue(newParachute.dragCoefficient, forKey: CoreData.dragCoefficient) //Measurement
        parachute.setValue(newParachute.mass, forKey: CoreData.mass) //Measurement
        parachute.setValue(newParachute.material.rawValue, forKey: CoreData.material) //String
        parachute.setValue(newParachute.measurementType.rawValue, forKey: CoreData.measurementType)
        parachute.setValue(newParachute.shape.rawValue, forKey: CoreData.shape) //String
        parachute.setValue(newParachute.vented, forKey: CoreData.vented) //Bool
        if newParachute.vented {
            parachute.setValue(newParachute.ventDiameter, forKey: CoreData.ventDiameter)//Optional Measurement
        }

        saveInCoreData()
    }

    private func saveInCoreData() {

        do {
            try DatabaseController().getContext().save()
        } catch let error {
            print(error)
        }
    }
}

class DatabaseController: NSObject {

    static let sharedInstance = DatabaseController()

    override init() {}

    public func getContext() -> NSManagedObjectContext {

        return DatabaseController.sharedInstance.persistentContainer.viewContext
    }

    public var fetchPredicate : NSPredicate?

    // MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {

        let container = NSPersistentContainer(name: "Recovery")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {

                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext

        if context.hasChanges {
            do {
                try context.save()
            } catch {

                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }
}

崩溃的原因是 func configureFetchedResultsController() { let context = databaseController.getContext() let parachutesFetchRequest = NSFetchRequest<Parachute>(entityName: CoreData.parachute) let primarySortDescriptor = NSSortDescriptor(key: CoreData.material, ascending: true) let secondarySortDescriptor = NSSortDescriptor(key: "diameter.value", ascending: true) let sortDescriptor = [primarySortDescriptor, secondarySortDescriptor] parachutesFetchRequest.sortDescriptors = sortDescriptor self.fetchedResultsController = NSFetchedResultsController<Parachute>( fetchRequest: parachutesFetchRequest, managedObjectContext: context, sectionNameKeyPath: CoreData.material, cacheName: nil) self.fetchedResultsController.delegate = self } 。直径是一个测量,这似乎不适合FRC的排序。当我将代码更改为let secondarySortDescriptor = NSSortDescriptor(key: "diameter", ascending: true)以希望按值排序时,我收到以下错误:

  

NSManagedObjectContextObjectsDidChangeNotification。 [valueForUndefinedKey:]:此类不是键值   符合编码的键值。 with userInfo {       NSTargetObjectUserInfoKey =“value:0.304800 unit:m”;       NSUnknownUserInfoKey = value; }

是否可以按测量排序,如果是,可以如何排序?

感谢所有提供帮助我缩小问题范围的人。

1 个答案:

答案 0 :(得分:0)

正如我在编辑中指出的那样,该问题与Core Data保存无关。一旦保存发生并且更新了FetchedResultsController(frc),就会导致崩溃。它基于我的sortDescriptors,其中一个是Measurement。虽然我无法确定对Measurement进行排序所需的语法(如果有的话),但对Core Data中的另一个属性进行排序可以防止崩溃。对于将来对此进行研究的人,我尝试对Measurement本身和测量值进行排序,这两者都会导致运行时崩溃。所以,我正在将这个问题标记为我最初的问题。

如果因比较声明而导致崩溃,请查看您的frc作为原因。