保存时未解决的错误

当我试图保存核心数据时,我收到了一个奇怪的错误消息 但问题是错误是不可重复的(它出现在不同的时间,当做不同的任务)

错误信息:

Unresolved error Domain=NSCocoaErrorDomain Code=1560 UserInfo=0x14f5480 "Operation could not be completed. (Cocoa error 1560.)", {
NSDetailedErrors = (
Error Domain=NSCocoaErrorDomain Code=1570 UserInfo=0x5406d70 "Operation could not be completed. (Cocoa error 1570.)",
Error Domain=NSCocoaErrorDomain Code=1570 UserInfo=0x14f9be0 "Operation could not be completed. (Cocoa error 1570.)"
);
}

产生错误的方法是:

- (IBAction)saveAction:(id)sender {
NSError *error;
if (![[self managedObjectContext] save:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@, %@", error, [error userInfo],[error localizedDescription]);
exit(-1);  // Fail
}
}

知道为什么这条信息会随机出现吗

77358 次浏览

意思是强制性财产被分配为零。无论是在你的 * 。Xcodatamodel 选中“可选”框,或者在保存到 ManagedObjectContext 时确保填入了属性。

如果在更改代码以满足这两个要求之后出现更多错误,请尝试清除构建并从 iPhone Simulator/iPhone 设备中删除应用程序。您的模型更改可能与旧的模型实现冲突。

编辑:

我差点忘了这里有核心数据公司吐出的所有错误代码: 核心数据常数参考 我以前在这方面遇到过麻烦,我意识到我没有选中正确的选项框。发现问题真是麻烦。祝你好运。

我自己也为此挣扎了一段时间。这里真正的问题在于,所进行的调试没有向您显示问题所在。这是因为 CoreData 会在“顶级”NSERror 对象中放入一个 NSERror 对象数组,如果有多个问题,它会返回这个数组(这就是为什么你会看到错误1560,它表示多个问题,和一个错误1570的数组)。看起来 CoreData 有几个键,如果有问题会给你更多有用的信息(比如发生错误的实体,丢失的关系/属性等) ,它会用这些键将信息存储在它返回的错误中。用于检查 userInfo 字典的键可以在 参考文件在这里中找到。

这是我用来从保存期间返回的错误中获得合理输出的代码块:

    NSError* error;
if(![[survey managedObjectContext] save:&error]) {
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError* detailedError in detailedErrors) {
NSLog(@"  DetailedError: %@", [detailedError userInfo]);
}
}
else {
NSLog(@"  %@", [error userInfo]);
}
}

它将产生输出,告诉您缺少哪些字段,这使得修复问题更容易处理。

我把这个作为一个答案,即使它实际上更像是对查尔斯的片段的修饰。NSLog 的直接输出可能很难阅读和解释,因此我喜欢添加一些空白并调出一些关键的“ userInfo”键的值。

下面是我一直在使用的方法的一个版本(’_ sharedManagedObjectContext’是’[[[[ UIApplication sharedApplication ] committee ] manager edObjectContext ]’的 # Definition)

- (BOOL)saveData {
NSError *error;
if (![_sharedManagedObjectContext save:&error]) {
// If Cocoa generated the error...
if ([[error domain] isEqualToString:@"NSCocoaErrorDomain"]) {
// ...check whether there's an NSDetailedErrors array
NSDictionary *userInfo = [error userInfo];
if ([userInfo valueForKey:@"NSDetailedErrors"] != nil) {
// ...and loop through the array, if so.
NSArray *errors = [userInfo valueForKey:@"NSDetailedErrors"];
for (NSError *anError in errors) {


NSDictionary *subUserInfo = [anError userInfo];
subUserInfo = [anError userInfo];
// Granted, this indents the NSValidation keys rather a lot
// ...but it's a small loss to keep the code more readable.
NSLog(@"Core Data Save Error\n\n \
NSValidationErrorKey\n%@\n\n \
NSValidationErrorPredicate\n%@\n\n \
NSValidationErrorObject\n%@\n\n \
NSLocalizedDescription\n%@",
[subUserInfo valueForKey:@"NSValidationErrorKey"],
[subUserInfo valueForKey:@"NSValidationErrorPredicate"],
[subUserInfo valueForKey:@"NSValidationErrorObject"],
[subUserInfo valueForKey:@"NSLocalizedDescription"]);
}
}
// If there was no NSDetailedErrors array, print values directly
// from the top-level userInfo object. (Hint: all of these keys
// will have null values when you've got multiple errors sitting
// behind the NSDetailedErrors key.
else {
NSLog(@"Core Data Save Error\n\n \
NSValidationErrorKey\n%@\n\n \
NSValidationErrorPredicate\n%@\n\n \
NSValidationErrorObject\n%@\n\n \
NSLocalizedDescription\n%@",
[userInfo valueForKey:@"NSValidationErrorKey"],
[userInfo valueForKey:@"NSValidationErrorPredicate"],
[userInfo valueForKey:@"NSValidationErrorObject"],
[userInfo valueForKey:@"NSLocalizedDescription"]);


}
}
// Handle mine--or 3rd party-generated--errors
else {
NSLog(@"Custom Error: %@", [error localizedDescription]);
}
return NO;
}
return YES;
}

这使我能够看到“ NSValidationErrorKey”的值,当我在 OP 中遇到这个问题时,它直接指向我在试图保存之前忘记设置的非可选的 Core Data 实体。

当我将第二条记录保存到 CoreData 时,这个问题触动了我。 所有非可选的字段(关系)也没有使用 nil 填充,但是在错误输出中我注意到,第一个保存对象中的一个字段变成了 nil。有点奇怪?但是原因是非常微不足道的——当我在第二个对象中设置第一个对象时,一对一的关系使它无效。

计划是这样的:

"Parent" with relationship "child" One to One
Create Child 1, set parent. Save - OK
Create Child 2, set parent. Save - Error, Child 1.Parent == nil
(behind the scene child 2 did nullify child 1 parent)

将“父母”中的关系从“一个”改为“多个”解决了这个问题。

类型 int 的瞬态属性是非可选的。显然,当它被设置为0时,就会出现1570错误。只是把我所有的临时属性改成了可选属性。如果需要,Nil-check 逻辑可以在代码中实现。

我的意思是,您的模型无法验证,这可能发生的原因有很多: 在您的模型中未使用的属性,缺少标记为必需的值。 为了更好地理解到底出了什么问题,可以在准备保存对象的位置放置一个断点,然后调用 validateFor...方法变量之一,比如:

po [myObject validateForInsert]

关于这个问题的更详细的信息在错误描述中。成功的验证意味着您将得不到任何输出。

它帮了我,再看看这个。

选中 * . xcodatamodel 对象中的 可以选择