ios iphone Core Data 保存时出现未解决的错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1283960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iphone Core Data Unresolved error while saving
提问by Ahmed Kotb
I am getting a strange error message from the core data when trying to save but the problem that the error is not reproducible ( it appears at different times when doing different tasks)
尝试保存时,我从核心数据收到一条奇怪的错误消息,但错误不可重现的问题(在执行不同任务时出现在不同时间)
the error message:
错误信息:
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.)"
);
}
and the method that generates the error is:
产生错误的方法是:
- (IBAction)saveAction:(id)sender {
NSError *error;
if (![[self managedObjectContext] save:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@, %@", error, [error userInfo],[error localizedDescription]);
exit(-1); // Fail
}
}
any idea for the reason of this message ? giving that it appears at random times
对此消息的原因有什么想法吗?让它出现在随机时间
回答by David Wong
It means there's a mandatory property has been assigned nil. Either in your *.xcodatamodel check the "optional" box or when you are saving to the managedObjectContext make sure that your properties are filled in.
这意味着有一个强制属性已被分配为零。在您的 *.xcodatamodel 中选中“可选”框,或者在保存到 managedObjectContext 时确保填写了您的属性。
If you're getting further errors after changing your code to suit the two requirements try cleaning your build and delete the application from your iPhone Simulator/iPhone device. Your model change may conflict with the old model implementation.
如果在更改代码以满足这两个要求后遇到更多错误,请尝试清理构建并从 iPhone 模拟器/iPhone 设备中删除应用程序。您的模型更改可能与旧模型实现冲突。
Edit:
编辑:
I almost forgot here's all the error codes that Core Data spits out: Core Data Constants ReferenceI had trouble with this before and I realised I unchecked the correct optional box. Such trouble finding out the problem. Good luck.
我几乎忘记了 Core Data 吐出的所有错误代码: Core Data Constants Reference我以前遇到过这个问题,我意识到我取消了正确的可选框。发现问题这么麻烦。祝你好运。
回答by Charles
I struggled with this for a little while myself. The real problem here is that the debugging you've got isn't showing you what the problem is. The reason for this is because CoreData will put an array of NSError objects in the "top level" NSError object it returns if there is more than one problem (This is why you see error 1560, which indicates multiple problems, and an array of error 1570s). It appears that CoreData has a handful of keys it uses to stash information in the error it returns if there is an issue that will give you more useful information (Such as the entity the error occurred on, the relationship/attribute that was missing, etc). The keys you use to inspect the userInfo dictionary can be found in the reference docs here.
我自己也为此挣扎了一段时间。这里真正的问题是您进行的调试并没有向您展示问题所在。这样做的原因是因为 CoreData 会将一个 NSError 对象数组放在它返回的“顶级” NSError 对象中,如果有多个问题(这就是为什么你会看到错误 1560,这表明存在多个问题,以及一个错误数组1570 年代)。如果存在可以为您提供更多有用信息的问题(例如发生错误的实体、丢失的关系/属性等),CoreData 似乎有一些键用于将信息存储在它返回的错误中)。用于检查 userInfo 字典的键可以在此处的参考文档中找到。
This is the block of code I use to get reasonable output from the error returned during a save:
这是我用来从保存期间返回的错误中获得合理输出的代码块:
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]);
}
}
It will produce output that tells you the fields that are in missing, which makes fixing the problem significantly easier to deal with.
它将产生输出,告诉您缺少的字段,这使得解决问题变得更加容易。
回答by clozach
I'm throwing this in as an answer, even though it's really more of an embellishment to Charles' snippet. The straight output from NSLog can be a mess to read and interpret, so I like to throw in some white space and call out the value of some critical 'userInfo' keys.
我把这个作为答案,尽管它实际上更像是对查尔斯片段的点缀。NSLog 的直接输出读起来和解释起来可能会很混乱,所以我喜欢加入一些空白并调出一些关键的“userInfo”键的值。
Here's a version of the method I've been using. ('_sharedManagedObjectContext' is a #define for '[[[UIApplication sharedApplication] delegate] managedObjectContext]'.)
这是我一直在使用的方法的一个版本。(“_sharedManagedObjectContext”是“[[[UIApplication sharedApplication] delegate] managedObjectContext]”的#define。)
- (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;
}
This allows me to see the value for 'NSValidationErrorKey', which, when I encountered the issue from the OP, pointed directly to the non-optional Core Data entities that I'd forgot to set before trying to save.
这使我能够看到“NSValidationErrorKey”的值,当我遇到来自 OP 的问题时,该值直接指向我在尝试保存之前忘记设置的非可选核心数据实体。
回答by HotJard
The problem touched me, when I save second record to CoreData. All not optional fields (relationship) was filled without nil as well, but in the error output I'd notice, that one of fields in first saved object had became nil. Strange a little? But the reason is quite trivial - one to one relationship which nullify first object, when I set it in the second.
当我将第二条记录保存到 CoreData 时,这个问题触动了我。所有非可选字段(关系)也没有填充,但在错误输出中我注意到,第一个保存的对象中的一个字段已变为 nil。有点奇怪?但原因很简单 - 当我在第二个对象中设置它时,一对一的关系会使第一个对象无效。
So, the scheme is:
所以,方案是:
"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)
Changing the relationship in Parent from One to One to Many to One solved this task.
将 Parent 中的关系从一对一改为多对一解决了这个任务。
回答by Anton Plebanovich
I had transient property of type int that wasn't optional. Obviously, when it was set to 0, 1570 error appear. Just changed all my transient properties to optional. Nil-check logic can be implemented in code if necessary.
我有一个不是可选的 int 类型的瞬态属性。显然,当它设置为 0 时,会出现 1570 错误。只是将我所有的瞬态属性更改为可选。如有必要,可以在代码中实现 Nil-check 逻辑。
回答by kkodev
I means that your model failed to validate, which could happen for a number of reasons: unused property in your model, missing value that's marked as required.
To get a better understanding of what exactly went wrong, put a breakpoint in a place where you are ready to save your object, and call one of the validateFor...
method variants, like:
我的意思是您的模型未能验证,这可能有多种原因:模型中未使用的属性,缺少标记为必需的值。为了更好地了解究竟出了什么问题,请在您准备保存对象的地方放置一个断点,然后调用其中一个validateFor...
方法变体,例如:
po [myObject validateForInsert]
po [myObject validateForInsert]
More detailed information about the problem is in error description. Successful validation means you will get no output.
有关问题的更多详细信息在错误描述中。成功的验证意味着您不会得到任何输出。
回答by ssowri1
It helped me. Check this one too.
它帮助了我。也检查这个。
Check the optionalbox in your *.xcodatamodel objects
检查*.xcodatamodel 对象中的可选框