прошивкой ядра данных - сохранить неудачной после использования удалить методы в NSManagedObject подклассы
Обзор:
- я удаляю NSManagedObject, используя методы remove, представленные в автогенерированный подкласс NSManagedObject
- Затем я пытаюсь сохранить базу данных
- сохранение базы данных не удалось.
.
- (void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h
Однако добавление NSManagedObject с помощью метода add позволяет успешно сохранить базу данных
- (void)addEmployeesObject:(Employee *)value; //Auto generated method in Department.h - works fine
Примечание: я использую подклассы NSManagedObject, созданные В Xcode.
Сведения О Сущности:
- у меня есть 2 таблицы (сущности), а именно "сотрудник"и" отдел "
- один отдел может содержать несколько сотрудников
- один сотрудник может принадлежать только к одному отделу
Детали Отношений:
- Отношение от "сотрудника" к "отделу"является отношением один к одному и называется "какой отдел". Удалить правило обнулить
- отношение от "Отдела" К "Сотрудник" - это отношение"многие к одному", которое называется "сотрудники". Правило удаления-Каскад
Задача:
Класс"Department" имеет метод, который называется, как указано ниже, после того, как я использую этот метод, сохранение базы данных не является успешным
(void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h //does not work
Код, используемый для удаления:
- (void) removeEmployeesHavingAgeAsZeroWithDepartment: (Department*) department
{
NSMutableSet *employeesSetToBeRemoved = [[NSMutableSet alloc] init];
for(Employees *currentEmployee in department.employees)
{
if(currentEmployee.age == 0)
{
[employeesSetToBeRemoved addObject:currentEmployee];
}
}
[department removeEmployees:employeesSetToBeRemoved]; //causing the problem
}
Код, используемый для сохранения базы данных
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
{NSLog(@"DB saved");}];
Вопросы:
- Почему сохранение базы данных не удается после использования удалить методы?
- нужно ли мне реализовать этот метод ? в настоящее время я не вижу никакой реализации для этого метода, я могу найти его только в заголовочном файле.
- Правильно ли настроены мои отношения (обратные, правила удаления и т. д.)?
Ответ:
- пожалуйста, обратитесь к ответу и комментариям Джоди (17 мая в 4: 39), он хорошо объяснил, как отладить проблему и найти первопричину
2 ответа:
Я держу пари, что вы не сохраняете свой контекст. При удалении объекта он просто помечается для удаления при следующем сохранении контекста.
Если вы вызовете isDeleted на каждом из этих объектов, что вы получите обратно?
EDIT
Ах... Я вижу, что вы используете UIManagedDocument (я могу сказать по вызову save, который вы используете). Вы должны предоставить полную информацию в ваших вопросах, особенно , когда имеете дело с CoreData, потому что у него так много ручек и взаимодействия.
Итак, во-первых, UIManagedDocument-это "безжизненная" архитектура. Вы не должны прибегать к вызову saveToURL при использовании UIManangedDocument.Он автоматически сохранится в фоновом потоке. Однако вы должны сказать ему, что есть обновления для изменения.
Кроме того, откуда вы знаете, что это не спасение? Я знаю, что это звучит как странный вопрос, но важно знать, на что вы смотрите и как вы определяете, что документ является не спасает. В документации говорится, что если вы хотите сэкономить, вам нужно сделать одно из двух.
- используйте UndoManager и пусть он помечает грязные вещи
- вызов [document updateChangeCount:UIDocumentChangeDone];
Теперь фактическое сохранение произойдет в какой-то момент в будущем. Однако некоторые вещи (например, переход в фоновый режим) вызовут сохранение.
Опять же, откуда вы знаете, что данные не сохранились?
Ты просто смотришь на управляемый объект, извлекаемый из MOC, просматривающий файл?
Добавить
[self.database updateChangeCount:UIDocumentChangeDone];
В конце этой функции удаления, и ваши данные, несомненно, будут сохранены.
EDIT
К сожалению, если вы получаете ошибку, сохранение фона может молча завершиться неудачей. Таким образом, вы должны следить за уведомлениями об изменении статуса, так как это единственное уведомление, которое вы получите, когда произойдет ошибка SN.
В то время как вы получите уведомление, когда статус изменится в результате ошибка, вы не получите никаких подробностей о причине ошибки. Чтобы получить это, вам придется переопределить handleError: userInteractionPermitted: в подклассе UIManagedDocument, если вы хотите получить фактические данные NSError.
Я бы зарегистрировался для уведомлений об изменении статуса и предоставил простой подкласс UIManagedDocument с handleError:userInteractionPermitted: overridden для регистрации ошибок. Посмотрим, что это тебе скажет. Надеюсь, это приведет вас к тому, почему ваше спасение не является событие.
Кроме того, не забывайте, что вы должны ждать сохранения.
Наконец, если вы хотите увидеть, что CoreData делает на уровне SQL, установите debugging (- com.яблоко.CoreData.SQLDebug 1)в параметрах командной строки для просмотра инструкций SQLLite.