保存时iphone Core Data Unresolved错误

时间:2009-08-16 10:19:48

标签: iphone objective-c ios core-data

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

错误消息:

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

任何关于此消息的原因的想法?让它随机出现

7 个答案:

答案 0 :(得分:292)

这意味着强制属性已被指定为零。在* .xcodatamodel中检查“可选”框或保存到managedObjectContext时确保填写了属性。

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

编辑:

我差点忘了这里核心数据吐出的所有错误代码: Core Data Constants Reference 之前我遇到了麻烦,我意识到我取消选中了正确的可选框。找出问题的麻烦。祝你好运。

答案 1 :(得分:232)

我自己挣扎了一会儿。这里真正的问题是你得到的调试并没有告诉你问题是什么。原因是因为如果存在多个问题,CoreData会将NSError对象的数组放入它返回的“顶级”NSError对象中(这就是为什么你看到错误1560,这表明存在多个问题,以及一个错误数组) 16世纪70年代)。看起来CoreData有一些密钥用于存储它返回的错误中的信息,如果存在可以提供更多有用信息的问题(例如发生错误的实体,缺少的关系/属性等等) )。您可以在the reference docs here

中找到用于检查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]);
        }
    }

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

答案 2 :(得分:21)

我把它作为一个答案,尽管这更像是对Charles的片段的修饰。 NSLog的直接输出可能是一个混乱的读取和解释,所以我喜欢抛出一些空格并调出一些关键的'userInfo'键的值。

这是我一直使用的方法的一个版本。 ('_sharedManagedObjectContext'是'[[[UIApplication sharedApplication]委托] managedObjectContext的'#fine]'。)

- (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实体。

答案 3 :(得分:0)

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

将父对象中的关系从一对一更改为多对一解决了此任务。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

po [myObject validateForInsert]

有关此问题的更多详细信息,请参阅错误说明。成功验证意味着您将无法获得输出。

答案 6 :(得分:0)

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

选中* .xcodatamodel对象中的可选