问题描述
我有一个CoreData实体 SavedWorkout
。它具有以下属性:
I have a CoreData Entity SavedWorkout
. It has the following attributes:
completionCounter
是一个 Bool
的数组,而 workout
是一个名为 Workout $的自定义类。 c $ c>。
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实体的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!