保存中のiphone Core Data Unresolvedエラー


169

保存しようとするとコアデータから奇妙なエラーメッセージが表示されますが、エラーを再現できないという問題があります(さまざまなタスクを実行すると、さまざまなタイミングで表示されます)

エラーメッセージ:

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コアデータ『生産』エラー処理」stackoverflow.com/questions/2262704/...
ヨハネスFahrenkrug

回答:


296

これは、必須プロパティにnilが割り当てられていることを意味します。* .xcodatamodelで「オプション」ボックスをオンにするか、managedObjectContextに保存するときに、プロパティが入力されていることを確認してください。

2つの要件に合わせてコードを変更した後にさらにエラーが発生する場合は、ビルドをクリーンアップして、iPhoneシミュレーター/ iPhoneデバイスからアプリケーションを削除してください。モデルの変更は、古いモデルの実装と競合する可能性があります。

編集:

Core Dataが出力するすべてのエラーコードをここに忘れてしまいました。CoreData Constants Reference 以前に問題があり、正しいオプションボックスをオフにしたことに気付きました。そのような問題を見つけるのは難しい。幸運を。


2
これで解決しました。また、少なくとも私の経験では、sqliteファイルに保存されていなくても、変更がコンテキストに反映されていることに注意してください。したがって、これが発生すると、動作が不安定になる可能性があります。
nickthedude 2013

根本的な原因を理解することはできませんでしたが、すべてのプロパティをオプションにすることで問題を解決することができました。
マイケル・オソフスキー2014

チャールズのコードを試してみたら、どのフィールドが問題であるかがわかります。
David Wong

233

私はしばらくの間、これに苦労しました。ここでの本当の問題は、あなたが得たデバッグが問題が何であるかを示していないことです。これは、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]);
        }
    }

欠落しているフィールドを示す出力が生成されるため、問題の修正が非常に簡単になります。


このコードをたくさんありがとう。これにより、CoreDataの問題追跡が非常に簡単になります。
MiKL、2011

21

チャールズのスニペットの装飾ではありますが、私はこれを答えとして投入します。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コアデータエンティティの説明文字列を取得した場合。
Lukasz

きちんと。「メッセージ」は未使用です。
pojo

0

CoreDataに2番目のレコードを保存すると、問題が発生しました。オプションではないすべてのフィールド(関係)もnilなしで入力されましたが、エラー出力では、最初に保存されたオブジェクトのフィールドの1つがnilになったことに気付きました。ちょっと変?しかし、その理由は非常に簡単です。最初のオブジェクトを2番目に設定すると、1対1の関係が無効になります。

したがって、スキームは次のとおりです。

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

親の関係を1対1から多対1に変更することで、このタスクは解決しました。


0

オプションではないint型の一時的なプロパティがありました。明らかに、0に設定すると、1570エラーが表示されます。一時的なプロパティをすべてオプションに変更しただけです。Nil-checkロジックは、必要に応じてコードに実装できます。


0

つまり、モデルが検証に失敗したことを意味します。これは、いくつかの理由で発生する可能性があります。モデルの未使用のプロパティ、必須としてマークされている値が欠落しています。正確に何が悪いのかをよりよく理解するには、オブジェクトを保存する準備ができている場所にブレークポイントを置きvalidateFor...、次のようなメソッドのバリアントの1つを呼び出します。

po [myObject validateForInsert]

問題の詳細については、エラーの説明を参照してください。検証が成功すると、何も出力されません。


0

それは私を助けました。こちらもチェック。

チェックオプションのあなた* .xcodatamodelオブジェクトにボックスを

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.