iphone Çekirdek Verileri Kaydedilirken çözülemeyen hata


169

Kaydetmeye çalışırken temel verilerden garip bir hata mesajı alıyorum, ancak hatanın tekrar üretilememesi sorunu (farklı görevler yaparken farklı zamanlarda görünüyor)

hata mesajı:

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.)"
);
}

ve hatayı oluşturan yöntem:

- (IBAction)saveAction:(id)sender {
    NSError *error;
    if (![[self managedObjectContext] save:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@, %@", error, [error userInfo],[error localizedDescription]);
        exit(-1);  // Fail
    }
}

Bu mesajın nedeni hakkında bir fikrin var mı? rastgele zamanlarda ortaya çıkmasını sağlamak


Bu size yardımcı olabilir: "iPhone Temel Verileri" Üretim "Hata İşleme" stackoverflow.com/questions/2262704/…
Johannes Fahrenkrug

Yanıtlar:


296

Bu, zorunlu bir mülkün sıfır olarak atandığı anlamına gelir. * .Xcodatamodel öğenizde "isteğe bağlı" kutusunu işaretleyin veya yönetilenObjectContext'e kaydederken özelliklerinizin doldurulduğundan emin olun.

Kodunuzu iki gereksinime uyacak şekilde değiştirdikten sonra başka hatalarla karşılaşıyorsanız, derlemenizi temizlemeyi ve uygulamayı iPhone Simulator / iPhone cihazınızdan silmeyi deneyin. Model değişikliğiniz eski model uygulamasıyla çakışabilir.

Düzenle:

Temel Verilerin tükettiği tüm hata kodlarını neredeyse unutuyordum: Temel Veri Sabitleri Referansı Daha önce bununla ilgili sorun yaşadım ve doğru isteğe bağlı kutunun işaretini kaldırdığımı fark ettim. Sorunu bulmak böyle bir sorun. İyi şanslar.


2
Bu benim için çözdü. Ayrıca, en azından deneyimlerime göre, sqlite dosyasına kaydedilmemiş olsa da, değişikliklerin içeriğe dönüştüğünü unutmayın. Bu durumda, davranış düzensiz olabilir.
nickthedude

Kök nedenini alamadım, ancak tüm özellikleri isteğe bağlı yaparak sorunu ortadan kaldırmayı başardım.
Michael Osofsky

Charles'ın kodunu denedin mi, sorunun hangi alanda olduğunu söylerdi.
David Wong

233

Bir süre bununla kendim mücadele ettim. Buradaki asıl sorun, sahip olduğunuz hata ayıklamanın size sorunun ne olduğunu göstermemesi. Bunun nedeni, CoreData'nın birden fazla sorun varsa döndürdüğü "üst düzey" NSError nesnesine bir dizi NSError nesnesi koymasıdır (Bu nedenle, birden fazla sorunu ve hata dizisini gösteren 1560 hatasını görüyorsunuz. 1570s). CoreData'nın, size daha yararlı bilgiler verecek bir sorun varsa, döndürdüğü hatadaki bilgileri saklamak için kullandığı bir avuç anahtarı vardır (Hatanın oluştuğu varlık, eksik olan ilişki / öznitelik vb. ). UserInfo sözlüğünü incelemek için kullandığınız tuşlar burada referans dokümanlarında bulunabilir .

Bu bir kayıt sırasında döndürülen hata makul çıktı almak için kullandığım kod bloğudur:

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

Eksik olan alanları size bildiren bir çıktı üretecek, bu da sorunun çözülmesini önemli ölçüde kolaylaştırmaktadır.


Bu kod için çok teşekkürler. CoreData problem takibini gerçekten daha basit hale getirir.
MiKL

21

Charles'ın pasajını daha çok süslemesine rağmen bunu bir cevap olarak veriyorum. NSLog'dan gelen düz çıktı okumak ve yorumlamak için bir karışıklık olabilir, bu yüzden bazı beyaz boşluklara atmak ve bazı kritik 'userInfo' anahtarlarının değerini çağırmak istiyorum.

İşte kullandığım yöntemin bir sürümü. ('_sharedManagedObjectContext' '[[[UIApplication sharedApplication] delegesi] yönetilenObjectContext]' için #defindir.)

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

Bu, OP'den sorunla karşılaştığımda, kaydetmeye çalışmadan önce ayarlamayı unuttuğum isteğe bağlı olmayan Temel Veri varlıklarına işaret eden 'NSValidationErrorKey' değerini görmemi sağlıyor.


Ayrıca çok faydalı. Özellikle bu ham \ n \ n \ n temel veri varlığı açıklama dizelerini aldığınızda.
Lukasz

Temiz. 'message' btw kullanılmıyor.
pojo

0

CoreData'ya ikinci kaydı kaydettiğimde sorun bana dokundu. İsteğe bağlı olmayan tüm alanlar (ilişki) sıfır olmadan dolduruldu, ancak hata çıktısında ilk kaydedilen nesnedeki alanlardan birinin sıfır olduğunu fark ettim. Biraz garip mi? Ama nedeni oldukça önemsiz - ikinci nesneyi ayarladığımda, ilk nesneyi geçersiz kılan bire bir ilişki.

Yani, şema:

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

Üst öğe içindeki ilişkinin Bir'den Bire Bire Bir Değiştirilmesi bu görevi çözdü.


0

İsteğe bağlı olmayan tür int geçici özelliği vardı. Açıkçası, 0 olarak ayarlandığında, 1570 hatası görünür. Tüm geçici özelliklerimi isteğe bağlı olarak değiştirdim. Gerekirse Nil-check mantığı kodda uygulanabilir.


0

Modelinizin doğrulanamadığı anlamına gelir, bu da birkaç nedenden dolayı olabilir: modelinizde kullanılmayan özellik, gerektiği gibi işaretlenmiş eksik değer. Neyin yanlış gittiğini daha iyi anlamak için, nesnenizi kaydetmeye hazır olduğunuz bir yere bir kesme noktası koyun ve aşağıdaki validateFor...gibi yöntem değişkenlerinden birini çağırın :

po [myObject validateForInsert]

Sorun hakkında daha ayrıntılı bilgi hata açıklamasındadır. Başarılı doğrulama, hiçbir çıktı almayacağınız anlamına gelir.


0

Bana yardımcı oldu. Bunu da kontrol et.

Kontrol opsiyonel senin * .xcodatamodel nesneleri kutusunu

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.