本文介绍了如何在Swift 3中将自定义类保存为CoreData实体的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个CoreData实体 SavedWorkout 。它具有以下属性:

I have a CoreData Entity SavedWorkout. It has the following attributes:

completionCounter 是一个 Bool 的数组,而 workout 是一个名为 Workout

completionCounter is an array of Bool, and workout is a custom class called Workout.

我这样保存数据:

let saveCompletionCounter = currentCompletionCounter
let saveDate = Date() as NSDate
let saveRoutineIndex = Int16(currentWorkoutRoutine)
let saveWorkout = NSKeyedArchiver.archivedData(withRootObject: workout)

item.setValue(saveDate, forKey: "date")
item.setValue(saveWorkout, forKey: "workout")
item.setValue(saveRoutineIndex, forKey: "routineIndex")
item.setValue(saveCompletionCounter, forKey: "completionCounter")

do {
  try moc.save()
  print("save successful")
} catch {
  print("saving error")
}

其中 moc 是一个实例 NSManagedObjectContext 的对象,而 item NSManagedObject 的实例:

where moc is an instance of NSManagedObjectContext, and item is an instance of NSManagedObject:

moc = appDelegate.managedObjectContext
entity = NSEntityDescription.entity(forEntityName: "SavedWorkout", in: moc)!
item = NSManagedObject(entity: entity, insertInto: moc)

href = https://stackoverflow.com/questions/16305537/saving-custom-class-into-coredata>此和和此,我已经完成了锻炼类符合 NSObject NSCoding ,因此现在看起来像这样:

In accordance with this and this and this , I have made my Workout class conform to NSObject and NSCoding, so it now looks like this:

class Workout: NSObject, NSCoding {

  let name: String
  let imageName: String
  let routine: [WorkoutRoutine]
  let shortDescription: String

  required init?(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    imageName = aDecoder.decodeObject(forKey: "imageName") as! String
    routine = aDecoder.decodeObject(forKey: "routine") as! [WorkoutRoutine]
    shortDescription = aDecoder.decodeObject(forKey: "shortDescription") as! String
  }

  func encode(with aCoder: NSCoder) {
    aCoder.encode(name, forKey: "name")
    aCoder.encode(imageName, forKey: "imageName")
    aCoder.encode(routine, forKey: "routine")
    aCoder.encode(shortDescription, forKey: "shortDescription")
  }

  init(name: String, imageName: String, routine: [WorkoutRoutine], shortDescription: String) {
    self.name = name
    self.imageName = imageName
    self.routine = routine
    self.shortDescription = shortDescription
  }
}

但是我总是得到例程中的错误:aDecoder.decodeObject ...

错误说:

NSForwarding:警告:类'App.WorkoutRoutine'的对象0x60800002cbe0没有实现methodSignatureForSelector:-遇到麻烦

无法识别的选择器-[FitLift.WorkoutRoutineroutine replaceObjectForKeyedArchiver:]

为什么这会给我一个错误,而不是其他 Transformable 属性?如何将自定义类保存为CoreData实体的属性?

Why does this give me an error and not the other Transformable attribute? How do I save a custom class as a property of a CoreData entity?

推荐答案

问题是 WorkoutRoutine 本身是一个自定义类,由于出现错误,它不符合NSCoding,因此 aCoder.encode(routine,forKey: routine)真的不知道如何编码,以及 routine = aDecoder.decodeObject(forKey: routine)一样! [WorkoutRoutine] 不知道如何解码。

The issue is that WorkoutRoutine is itself a custom class and as of your error it is not NSCoding compliant, therefore aCoder.encode(routine, forKey: "routine") doesn't really know how to encode it, as well as routine = aDecoder.decodeObject(forKey: "routine") as! [WorkoutRoutine] doesn't know how to decode it.

虽然没什么关系,但是请为编码器和编码器初始化程序尝试一种更安全的方法因为如果编码器不包含您要查找的键(由于任何原因),力解开可能会导致崩溃

Not really related, but please try a safer approach for your coder and encoder initializer as the force unwrap might cause crashes if the encoder does not contain the keys you are looking for (for any reason)

required init?(coder aDecoder: NSCoder) {
    guard let name = aDecoder.decodeObject(forKey: "name") as? String,
        let imageName = aDecoder.decodeObject(forKey: "imageName") as? String,
        let routine = aDecoder.decodeObject(forKey: "routine") as? [WorkoutRoutine],
        let shortDescription = aDecoder.decodeObject(forKey: "shortDescription") as? String else {
            return nil
    }
    self.name = name
    self.imageName = imageName
    self.routine = routine
    self.shortDescription = shortDescription
}

这篇关于如何在Swift 3中将自定义类保存为CoreData实体的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 04:09