Swift 中的 CoreData NSFetchRequest 错误 NSInvalidArgumentException

CoreData NSFetchRequest error NSInvalidArgumentException in Swift 3

将我的项目更新为最新的 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)")
  }

错误发生在一行

let results = try userDataStack.context.fetch (requestSavedLevel) as? [LevelEntity]

它立即将我带到 AppDelegate 并显示 Thread 1: signal SIGABRT

控制台打印出消息: * 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'* -[NSDictionary initWithObjects:forKeys:]:对象计数 (0) 不同于键计数 ( 9)'

我不知道发生了什么,也不知道为什么代码不再有效。我在 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?

}

我要保存下一个数据到核心数据: 水平变量:[[Int]] 变种名称:字符串 变量形状:[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

时出现错误

ShapeNSObject.

的自定义 class、subclass

因此,当我尝试从 Core Data 获取数据时,我得到的结果是 对象数 (0) 与键数 (9) 不同'.

再一次,在我将项目更新到 Swift 3.

之前,很多个月一切都很好

我尝试使用 NSArchiver 来存档形状,然后将其作为 NSObject 分配给 entity.shapes,并且它有效,但如果它是唯一的解决方案,那么我必须更新大量代码。

为什么这不起作用有什么建议吗?

所以我解决了。 问题在于解码我的自定义 NSObject 子类。

aDecoder.decodeObject(forKey: "number") as? Int

decodeObject 没有 return 给我一个整数值,但我发现 decodeInteger 方法可以做到。

aDecoder.decodeInteger(forKey: "column")

然而,decodeInteger 方法有时也会导致崩溃,所以我得到了下一个条件:

var n = aDecoder.decodeObject(forKey: "number") as? Int
if n == nil {
    n = aDecoder.decodeInteger(forKey: "number")
}