将我的项目更新为最新的swift语法(Swift 3)后,我在执行CoreData获取请求时遇到错误。所以应用程序工作了好几个月,现在它已经坏了。
这就是我执行获取请求的方式。
let requestSavedLevel = NSFetchRequest<NSFetchRequestResult>(entityName: "LevelEntity")
let levelNamePredicate = NSPredicate(format: "levelName = %@", levelName)
requestSavedLevel.predicate = levelNamePredicate
do {
let results = try userDataStack.context.fetch(requestSavedLevel) as? [LevelEntity]
if (results?.count)! > 0 {
self.savedLevel = results?.first!
return results?.first!
}
}
catch {
print("\n Error on \(#function): \(error)")
}
错误发生在一行
让results = try userDataStack.context.fetch(requestSavedLevel)为? [LevelEntity]
它会立即将我带到AppDelegate并显示主题1:信号SIGABRT
控制台打印出消息: *由于未捕获的异常终止应用程序&#39; NSInvalidArgumentException&#39;,原因:&#39; * - [NSDictionary initWithObjects:forKeys:]:对象计数(0)与键计数不同(9)&#39;
我不知道发生了什么以及为什么代码不再有效。我在Swift 3中看到过有关CoreData问题的其他问题,但这并没有帮助。
*编辑*
我试图找到导致错误的原因,然后我找到了。 我的NSManagedObject具有这些属性 `扩展MyEntity {
@nonobjc public class func fetchRequest() -> NSFetchRequest< MyEntity > {
return NSFetchRequest< MyEntity >(entityName: "MyEntity");
}
@NSManaged public var horizontal: NSObject?
@NSManaged public var name: String?
@NSManaged public var shapes: NSObject?
}
我想将下一个数据保存到核心数据: var horizontal:[[Int]] var name:String var形状:[Int:Shape]
我这样做:
let entity = NSEntityDescription.insertNewObject(forEntityName: "MyEntity", into: userDataStack.context) as! MyEntity
entity.name = name
entity.horizontal = horizontal as NSObject
entity.shapes = shapes as NSObject
userDataStack.saveContext()
但是,当我尝试保存entity.shapes = shapes as NSObject
Shape 是 NSObject 的自定义类子类。
因此,当我尝试从Core Data获取数据时,我得到的是对象数(0)与键数(9)&#39; 不同。
同样,在我将项目更新到Swift 3之前,一切都运行了很多个月。
我尝试使用NSArchiver来存档形状,然后将它作为NSObject分配给entity.shapes,它可以工作,但如果它是唯一的解决方案,那么我必须更新很多代码。
为什么这不起作用的任何建议?
答案 0 :(得分:0)
所以我解决了。 问题在于解码我的自定义NSObject子类。
aDecoder.decodeObject(forKey: "number") as? Int
decodeObject 没有给我一个整数值,但我发现 decodeInteger 方法可以做到。
aDecoder.decodeInteger(forKey: "column")
然而, decodeInteger 方法有时也会导致崩溃,所以我最终得到了下一个条件:
var n = aDecoder.decodeObject(forKey: "number") as? Int
if n == nil {
n = aDecoder.decodeInteger(forKey: "number")
}