Я работаю с подклассом NSManagedObject. Фактически, он наследуется от класса, который наследуется от класса, который сам наследуется от NSManagedObject (это не должно быть проблемой, верно?).
Проблема
После того, как я внесу изменения в свойства объекта, объект запоминает изменения в течение своего времени жизни, но изменения никогда не сохраняются в базе данных.
Откуда мне это знать?
Я знаю это, потому что:
В базу данных ничего не записывается!
Контекст
Я использую автоматически сгенерированные методы делегата для создания координатора хранилища и контекста. Затем я передаю контекст контроллерам представления в их методах инициализации, как рекомендовано в документации. Хранилище - SQLite.
Я могу успешно вставлять объекты в базу данных и читать их. Я даже могу внести изменения в свойства только что вставленного объекта и успешно его сохранить. Кажется, я просто не могу обновить свойства объекта, когда объект извлекается из базы данных.
Объект извлекается из хранилища через связь с другим объектом. После внесения изменений в его свойства я вызываю метод сохранения контекста. Однако перед этим я вызываю метод объекта isUpdated и метод контекста hasChanges, и оба возвращают false. Разве они не должны возвращать истину, поскольку я только что внес изменения в свойства объекта, но не сохранил контекст?
Подробнее
Однако если я вызываю метод commitChanges объекта перед сохранением контекста, передавая имена свойств, которые я изменил, я возвращаю правильные значения свойств. Я не понимаю, что это значит. Я бы подумал, что это означает, что новые значения свойств объекта были успешно сохранены, но очевидно, что они не сохранены.
Я знаю, что объекты результата зарегистрированы в контексте. Если я вызываю
[[result managedObjectContext] refreshObject:result mergeChanges:YES];
, объект возвращается к исходным значениям свойств. Это означает, что контекст есть и что это тот же контекст, из которого была извлечена запись. А это означает, что новые значения свойств никогда не записываются в базу данных.
Some Code
Вот код, в котором я ковыряюсь со всеми этими вещами. В моем коде есть и другие места, где я изменяю свойства, но эти изменения никогда не сохраняются.
- (IBAction)statusControlChanged:(UISegmentedControl *)control {
WCAAssessmentResult *result = [self currentResult];
/* printing the existing property values */
if (![result.complete boolValue]) NSLog(@"result is in progress!");
else if ([result.passed boolValue]) NSLog(@"result is passed!");
else NSLog(@"result is not passed!");
/* changing the property values */
switch (control.selectedSegmentIndex) {
case 0:
NSLog(@"setting incomplete");
result.complete = [NSNumber numberWithBool:NO];
break;
case 1:
NSLog(@"setting passed");
result.passed = [NSNumber numberWithBool:YES];
result.complete = [NSNumber numberWithBool:YES];
break;
case 2:
NSLog(@"setting failed");
result.passed = [NSNumber numberWithBool:NO];
result.complete = [NSNumber numberWithBool:YES];
break;
default:
break;
}
/* this method always returns an empty dictionary */
NSLog(@"%@", [result changedValues]);
/* this method returns the values that I just set */
NSLog(@"%@", [result committedValuesForKeys:[NSArray arrayWithObjects:@"complete", @"passed", nil]]);
/* isUpdated returns false */
if (![result isUpdated]) {
NSLog(@"result is not updated?! WTF!?!?");
}
/* hasChanges returns false */
if (![[result managedObjectContext] hasChanges]) {
NSLog(@"context has no changes!? WTF!?!?");
}
/* saving the context produces no error */
NSError *error = nil;
if (![[result managedObjectContext] save:&error]) {
NSLog(@"save failed");
NSLog(@"%@",[error description]);
}
}
A Twist
Если я создаю новый объект результата, вставляя новую запись в контекст, я могу установить это свойства объекта, и они успешно сохранены. В приведенном выше коде я получаю объект как член ассоциации со многими из другого объекта. Это подсказка?
Я рву волосы из-за этого. Что, черт возьми, здесь может быть не так?
Что? s НЕ проблема
-com. аргумент apple.CoreData.SQLDebug 1
для записи в журнал Core Data SQL, и при обновлении и сохранении свойств объекта SQL не регистрируется.