CoreData:此 class 不符合键 folderPosition 的键值编码
CoreData: this class is not key value coding-compliant for the key folderPosition
已更新 - 具有以下解决方案的代码
我已经在许多不同的项目中使用了 CoreData,没有出现任何问题,但是这个让我很困惑。这个项目和之前项目的唯一区别是我使用的是 CloudKit.
我只想为当前记录设置一个值。我有一个名为 Folders 的实体,在该实体中有一个名为 folderPosition 的 Int16 属性。
我更新值的代码如下所示:
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [Folders] {
if fetchResults.count != 0 {
for items in fetchResults {
managedObjectContext.setValue(items.folderPosition - 1, forKey: "folderPosition")
}
}
}
try? managedObjectContext.save()
}
catch {
print("Catch")
}
}
但是我不断收到以下错误:
quotelibc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSManagedObjectContext 0x600001cb4c30> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key folderPosition.'
terminating with uncaught exception of type NSExceptionquote>
另一个奇怪的事情是,我有一个名为 folderName (String) 的属性,如果我使用相同的代码进行更新,我不会崩溃,而且我可以看到它遍历了 CoreData 中所有可用的文件夹并更新了值对于 folderName 但是当我取回数据时,文件夹名称没有改变。一切都很奇怪。
根据有用的评论和回答更新了代码 - 谢谢!
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [Folders] {
for (index, folder) in fetchResults.enumerated() {
folder.folderPosition = (Int16(index))
}
}
try? managedObjectContext.save()
}
catch {
print(error)
}
}
首先,与问题无关的是,重新索引位置的逻辑看起来很奇怪。实际上你只需要从位置 deleted position + 1.
处的项目减少索引
如评论中所述,错误是由错字引起的。你是说
items.setValue(items.folderPosition - 1, forKey: "folderPosition")
而不是
managedObjectContext.setValue(items.folderPosition - 1, forKey: "folderPosition")
代码中有很多不好的做法。
- 命名混乱。以单数形式命名实体和循环元素:
Folder
和 for item in ...
.
- 避免冗余信息。将
folderPosition
重命名为 position
- 比 KVC 更喜欢点符号。
- 利用通用提取请求:
NSFetchRequest<Folders>
。
- 切勿使用
count == 0
检查空字符串或空数组。有isEmpty
.
- 空支票无论如何都是多余的。如果数组为空,则跳过循环。
- 永远不要在
catch
块中打印无意义的文字字符串。打印 error
.
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<Folders>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
let folders = try managedObjectContext.fetch(fetchRequest)
for folder in folders {
folder.folderPosition = folder.folderPosition - 1
}
try managedObjectContext.save()
}
catch {
print(error)
}
}
要重新索引从 0 开始的整个数据集,有一种更聪明的方法:
for (index, folder) in folders.enumerated() {
folder.folderPosition = index
}
已更新 - 具有以下解决方案的代码
我已经在许多不同的项目中使用了 CoreData,没有出现任何问题,但是这个让我很困惑。这个项目和之前项目的唯一区别是我使用的是 CloudKit.
我只想为当前记录设置一个值。我有一个名为 Folders 的实体,在该实体中有一个名为 folderPosition 的 Int16 属性。
我更新值的代码如下所示:
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [Folders] {
if fetchResults.count != 0 {
for items in fetchResults {
managedObjectContext.setValue(items.folderPosition - 1, forKey: "folderPosition")
}
}
}
try? managedObjectContext.save()
}
catch {
print("Catch")
}
}
但是我不断收到以下错误:
quotelibc++abi.dylib: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSManagedObjectContext 0x600001cb4c30> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key folderPosition.' terminating with uncaught exception of type NSExceptionquote>
另一个奇怪的事情是,我有一个名为 folderName (String) 的属性,如果我使用相同的代码进行更新,我不会崩溃,而且我可以看到它遍历了 CoreData 中所有可用的文件夹并更新了值对于 folderName 但是当我取回数据时,文件夹名称没有改变。一切都很奇怪。
根据有用的评论和回答更新了代码 - 谢谢!
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [Folders] {
for (index, folder) in fetchResults.enumerated() {
folder.folderPosition = (Int16(index))
}
}
try? managedObjectContext.save()
}
catch {
print(error)
}
}
首先,与问题无关的是,重新索引位置的逻辑看起来很奇怪。实际上你只需要从位置 deleted position + 1.
处的项目减少索引如评论中所述,错误是由错字引起的。你是说
items.setValue(items.folderPosition - 1, forKey: "folderPosition")
而不是
managedObjectContext.setValue(items.folderPosition - 1, forKey: "folderPosition")
代码中有很多不好的做法。
- 命名混乱。以单数形式命名实体和循环元素:
Folder
和for item in ...
. - 避免冗余信息。将
folderPosition
重命名为position
- 比 KVC 更喜欢点符号。
- 利用通用提取请求:
NSFetchRequest<Folders>
。 - 切勿使用
count == 0
检查空字符串或空数组。有isEmpty
. - 空支票无论如何都是多余的。如果数组为空,则跳过循环。
- 永远不要在
catch
块中打印无意义的文字字符串。打印error
.
static func updateFolderPositionsAfterFolderDeletion(managedObjectContext: NSManagedObjectContext = AppDelegate.viewContext) {
let fetchRequest = NSFetchRequest<Folders>(entityName: "Folders")
let sortDescriptor = NSSortDescriptor(key: "folderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
do {
let folders = try managedObjectContext.fetch(fetchRequest)
for folder in folders {
folder.folderPosition = folder.folderPosition - 1
}
try managedObjectContext.save()
}
catch {
print(error)
}
}
要重新索引从 0 开始的整个数据集,有一种更聪明的方法:
for (index, folder) in folders.enumerated() {
folder.folderPosition = index
}