我有一个 CoreData 实体 SavedWorkout
。它具有以下属性:
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")
}
其中 moc
是 NSManagedObjectContext
的实例,item
是 NSManagedObject
的实例:
moc = appDelegate.managedObjectContext
entity = NSEntityDescription.entity(forEntityName: "SavedWorkout", in: moc)!
item = NSManagedObject(entity: entity, insertInto: moc)
根据this和 this而且,我已经使我的 Workout
类符合 NSObject
和 NSCoding
,所以它现在看起来像这样:
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/