iPhone 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
}
}
есть идеи по причине этого сообщения ? учитывая, что он появляется в случайные моменты времени
6 ответов:
Это означает, что обязательное свойство было присвоено nil. Либо в вашем *.xcodatamodel установите флажок "необязательно" или при сохранении в managedObjectContext убедитесь, что ваши свойства заполнены.
Если вы получаете дополнительные ошибки после изменения кода в соответствии с двумя требованиями, попробуйте очистить свою сборку и удалить приложение с вашего устройства iPhone Simulator/iPhone. Изменение модели может конфликтовать со старой моделью реализация.
Edit:
Я почти забыл вот все коды ошибок, которые выплевывает Core Data: Ссылка На Константы Основных Данных У меня были проблемы с этим раньше, и я понял, что я не правильный дополнительный ящик. Такие проблемы с выяснением проблемы. Удача.
Я сам некоторое время боролся с этим. Реальная проблема здесь заключается в том, что отладка у вас не отображается, в чем проблема. Причина этого заключается в том, что CoreData помещает массив объектов NSError в объект NSError "верхнего уровня", который он возвращает, если существует более одной проблемы (именно поэтому вы видите ошибку 1560, которая указывает на несколько проблем и массив ошибок 1570s). Похоже, что 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]); } }он будет производить вывод, который сообщает вам поля, которые отсутствуют, которые это значительно облегчает решение проблемы.
Я бросаю это в качестве ответа, хотя на самом деле это скорее украшение фрагмента Чарльза. Прямой вывод из NSLog может быть беспорядком для чтения и интерпретации, поэтому мне нравится бросать некоторые пробелы и вызывать значение некоторых критических ключей "userInfo".
вот версия метода, который я использовал. ('_sharedManagedObjectContext' - это #define для ' [[[UIApplication sharedApplication] делегат] managedObjectContext]'.)
- (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, которые я забыл установить перед попыткой сохранить.
проблема коснулась меня, когда я сохраняю вторую запись в 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)изменение отношения в Родительском от одного к одному ко многим Один решил эту задачу.
У меня было переходное свойство типа int, которое не было необязательным. Очевидно, что когда он был установлен в 0, появляется ошибка 1570. Просто изменил все мои переходные свойства на необязательные. При необходимости логика нулевой проверки может быть реализована в коде.
I означает, что ваша модель не прошла проверку, что может произойти по ряду причин: неиспользуемое свойство в вашей модели, отсутствующее значение, отмеченное как необходимое. Чтобы лучше понять, что именно пошло не так, поместите точку останова в место, где вы готовы сохранить свой объект, и вызовите один из
validateFor...варианты метода, например:
po [myObject validateForInsert]более подробная информация о проблеме находится в описании ошибки. Успешная проверка означает, что вы будете не получить никакого выхода.
Comments