저장하는 동안 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/…
Johannes Fahrenkrug

답변:


296

필수 속성이 없음을 의미합니다. * .xcodatamodel에서 "선택적"상자를 선택하거나 managedObjectContext에 저장할 때 특성이 채워져 있는지 확인하십시오.

두 가지 요구 사항에 맞게 코드를 변경 한 후 추가 오류가 발생하면 빌드를 정리하고 iPhone Simulator / iPhone 장치에서 응용 프로그램을 삭제하십시오. 모델 변경이 이전 모델 구현과 충돌 할 수 있습니다.

편집하다:

코어 데이터가 뱉어내는 모든 오류 코드는 거의 잊어 버렸습니다. 코어 데이터 상수 참조 이전에 문제가 있었으며 올바른 옵션 상자를 선택 취소했습니다. 문제를 찾는 데 어려움이 있습니다. 행운을 빕니다.


2
이것은 나를 위해 해결했습니다. 또한 적어도 내 경험상 sqlite 파일에 저장되지 않았지만 변경 사항이 컨텍스트에 적용되었습니다. 따라서이 문제가 발생하면 동작이 불규칙 할 수 있습니다.
nickthedude

근본 원인을 찾을 수는 없었지만 모든 속성을 선택적으로 만들어 문제를 해결했습니다.
Michael Osofsky

Charles의 코드를 사용해 보셨습니까? 어떤 필드가 문제인지 알려줍니다.
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

21

나는 이것이 Charles의 발췌 문장에 더 많은 장식이긴하지만 대답으로 던지고 있습니다. 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에서 문제가 발생했을 때 저장하기 전에 설정하지 않은 비 핵심 Core Data 엔터티를 직접 가리 켰습니다.


또한 매우 유용합니다. 특히이 원시 \ n \ n \ n 핵심 데이터 엔터티 설명 문자열을 얻을 때.
Lukasz

산뜻한. '메시지'는 btw에서 사용되지 않습니다.
pojo

0

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)

부모의 관계를 일대일에서 다대 일로 변경하면이 작업이 해결되었습니다.


0

선택 사항이 아닌 int 유형의 임시 속성이 있습니다. 분명히 0으로 설정되면 1570 오류가 나타납니다. 모든 일시적 속성을 옵션으로 변경했습니다. 필요한 경우 코드에서 논리 검사 논리를 구현할 수 있습니다.


0

모델의 유효성 검사에 실패했음을 의미합니다. 여러 가지 이유로 발생할 수 있습니다. 모델에서 사용되지 않은 속성, 필요한 것으로 표시된 값이 누락되었습니다. 정확히 무엇이 잘못되었는지 더 잘 이해하려면 객체를 저장할 준비가 된 곳에 중단 점을두고 다음 validateFor...과 같은 메소드 변형 중 하나를 호출하십시오 .

po [myObject validateForInsert]

문제에 대한 자세한 정보는 오류 설명에 있습니다. 성공적인 검증은 출력이 없다는 것을 의미합니다.


0

그것은 나를 도왔다. 이것도 확인하십시오.

* .xcodatamodel 객체에서 옵션 상자를 선택 하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.