【问题标题】:iphone Core Data Unresolved error while savingiphone核心数据保存时出现未解决的错误
【发布时间】:2010-11-20 00:23:24
【问题描述】:

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

错误信息:

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

关于这条消息的原因有什么想法吗?假设它随机出现

【问题讨论】:

标签: iphone objective-c ios core-data


【解决方案1】:

这意味着有一个强制属性被赋值为 nil。在您的 *.xcodatamodel 中选中“可选”框,或者在保存到 managedObjectContext 时确保您的属性已填写。

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

编辑:

我差点忘记了 Core Data 吐出的所有错误代码: Core Data Constants Reference 我之前遇到过这个问题,我意识到我没有选中正确的可选框。发现问题这么麻烦。祝你好运。

【讨论】:

  • 这为我解决了。另请注意,至少根据我的经验,即使它没有保存到 sqlite 文件,更改确实会进入上下文。因此,当这种情况发生时,行为可能会不稳定。
  • 我无法找到根本原因,但我设法通过将所有属性设为可选来解决问题。
  • 你试过查尔斯的代码,它会告诉你哪个字段有问题。
【解决方案2】:

我自己为此苦苦挣扎了一会儿。这里真正的问题是你得到的调试没有告诉你问题是什么。这样做的原因是,如果出现多个问题,CoreData 会将一组 NSError 对象放在它返回的“顶级” NSError 对象中(这就是为什么您会看到错误 1560,它表示多个问题,以及一组错误1570 年代)。如果存在可以为您提供更多有用信息的问题(例如发生错误的实体、丢失的关系/属性等),CoreData 似乎有一些键用于在返回的错误中存储信息)。用于检查 userInfo 字典的键可以在 the reference docs here 中找到。

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

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

它将生成输出,告诉您缺少的字段,这使得解决问题变得更加容易处理。

【讨论】:

  • 非常感谢这段代码。它确实使 CoreData 问题跟踪变得更加简单。
【解决方案3】:

我把这个作为答案,尽管它实际上更像是对查尔斯的 sn-p 的点缀。 NSLog 的直接输出可能难以阅读和解释,因此我喜欢添加一些空白并调出一些关键的 'userInfo' 键的值。

这是我一直在使用的方法的一个版本。 ('_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 的问题时,它直接指向我在尝试保存之前忘记设置的非可选核心数据实体。

【讨论】:

  • 也很有用。特别是当你得到这个原始的 \n\n\n 核心数据实体描述字符串时。
  • 整洁。顺便说一句,“消息”未使用。
【解决方案4】:

当我将第二条记录保存到 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)

将 Parent 中的关系从一对一更改为多对一解决了这个任务。

【讨论】:

    【解决方案5】:

    我有 int 类型的瞬态属性,它不是可选的。显然,当它设置为 0 时,就会出现 1570 错误。刚刚将我所有的瞬态属性更改为可选。如有必要,可以在代码中实现 Nil-check 逻辑。

    【讨论】:

      【解决方案6】:

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

      po [myObject validateForInsert]

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

      【讨论】:

        【解决方案7】:

        它帮助了我。也检查一下。

        选中 *.xcodatamodel 对象中的可选

        【讨论】:

          猜你喜欢
          • 2011-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-24
          • 2023-03-23
          • 1970-01-01
          • 2012-06-07
          • 1970-01-01
          相关资源
          最近更新 更多