iPhone核心数据保存时未解决的错误

尝试保存时,我收到了来自核心数据的奇怪错误消息,但错误不可重现的问题(在执行不同任务时出现在不同的时间)

错误消息:

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 } } 

任何想法为这个消息的原因? 让它随机出现

这意味着有一个强制性的财产已被分配零。 无论是在* .xcodatamodel检查“可选”框或当你保存到managedObjectContext请确保您的属性填写。

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

编辑:

我几乎忘了这里是所有的核心数据吐出的错误代码: 核心数据常量参考我有这个麻烦之前,我意识到我没有选中正确的选项框。 这样的麻烦发现问题。 祝你好运。

我为此挣扎了一会儿。 这里真正的问题是,你得到的debugging并没有告诉你问题是什么。 原因是因为CoreData会把NSError对象放在它返回的“顶层”NSError对象中,如果有多个问题的话(这就是为什么你会看到错误1560,这表明有多个问题,而且错误数组16世纪70年代)。 看来,CoreData有一些密钥,它用来存储错误中的信息,如果有问题会给你更多有用的信息(比如发生错误的实体,缺失的关系/属性等等) )。 用于检查userInfo字典的键可以在参考文档中find 。

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

  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]); } } 

它会产生输出,告诉你缺less的字段,这使得解决问题更容易处理。

我把这个问题作为答案,虽然这实际上更像是Charles的片段的点缀。 从NSLog的直接输出可能是一个混乱的阅读和解释,所以我喜欢扔一些空白,并呼吁一些关键的'用户信息'键的价值。

这是我一直使用的方法的一个版本。 ('_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; } 

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

当我将第二条logging保存到CoreData时,问题就触动了我。 所有不可选的字段(关系)都填充为零,但在错误输出中,我会注意到,第一个保存的对象中的一个字段已成为零。 奇怪了一点? 但是,原因是很微不足道的 – 当我把它放在第二个对象时,一对一的关系使第一个对象无效。

所以,这个计划是:

 "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) 

改变父母之间的关系从一对一到多对一解决了这个任务。

我有inttypes的瞬态属性,这是不可选的。 显然,当它被设置为0时,出现1570错误。 只是将我的所有瞬态属性更改为可选。 如有必要,可以用代码实现无核查逻辑。

我的意思是你的模型没有通过validation,这可能是由于以下原因造成的:模型中未使用的属性,缺less标记为必需的值。 为了更好地理解到底发生了什么问题,可以在准备保存对象的地方放置一个断点,然后调用其中一个validateFor...方法变体,例如:

po [myObject validateForInsert]

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