저장하는 동안 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.