swift - 如何在 Swift 3 中将自定义类保存为 CoreData 实体的属性?

标签 swift core-data

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

completionCounter 是一个 Bool 数组,workout 是一个名为 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")
}

其中 mocNSManagedObjectContext 的实例,itemNSManagedObject 的实例:

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

根据thisthis而且,我已经使我的 Workout 类符合 NSObjectNSCoding,所以它现在看起来像这样:

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
  }
}

但是我总是在 routine: aDecoder.decodeObject... 这行出错。

错误说:

NSForwarding:警告:类“App.WorkoutRoutine”的对象 0x60800002cbe0 未实现 methodSignatureForSelector:-- 麻烦了

无法识别的选择器 -[FitLift.WorkoutRoutine replacementObjectForKeyedArchiver:]

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

最佳答案

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

没有真正相关,但请为您的编码器和编码器初始化程序尝试一种更安全的方法,因为如果编码器不包含您正在寻找的 key (出于任何原因),强制解包可能会导致崩溃

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 - 如何在 Swift 3 中将自定义类保存为 CoreData 实体的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45211115/

相关文章:

core-data - 如何从 MKMapItem 中提取纬度/经度坐标

arrays - 如何在 Swift 中使用区分大小写和不区分大小写的混合字符串避免 Array 中的重复条目?

ios - 检查 coredata 对象是否为 nil

swift - 当 View 改变时计时器终止

ios - 协议(protocol)和委托(delegate)不起作用..我做错了什么?

json - swift 如何检查来自 Json 的 NULL 值

ios - 删除行时极少发生的 TableView 错误 - 核心数据和 FetchedResultsController

iphone - 关于数据模型的思考

ios - Swift:无法将类型 '__NSCFArray' 的值转换为 'NSDictionary'

swift - 如何修复 loadPersistentStores 在加载时崩溃