我正在使用 NSManagedObject 的子类。实际上,它继承自一个继承自 NSManagedObject 的类的类(这应该不是问题,对吧?)。
问题
在我更改对象的属性后,该对象会在其生命周期内记住这些更改,但这些更改永远不会保存到数据库中。
我怎么知道?
我知道这是因为:
什么都没有写入数据库!
语境
我正在使用自动生成的委托(delegate)方法来创建商店协调器和上下文。然后我按照文档中的建议将上下文传递到 View Controller 的 init 方法中。商店是 SQLite。
我能够成功地将对象插入数据库并读取它们。我什至可以对新插入的对象进行属性更改并成功保存。当对象从数据库中拉出时,我似乎无法更新对象属性。
该对象是通过与另一个对象的关系从商店中获取的。更改其属性后,我调用上下文的 save 方法。但是,在这样做之前,我调用了对象的 isUpdated 方法和上下文的 hasChanges 方法,两者都返回 false。因为我刚刚更改了对象的属性但尚未保存上下文,所以它们不应该返回 true 吗?
更多
如果我在保存上下文之前调用对象的 commitChanges 方法,但是,传入我已更改的属性的名称,我会返回正确的属性值。我不确定这意味着什么。我原以为这意味着对象的新属性值已成功保存,但显然它们没有保存。
我知道结果对象是用上下文注册的。如果我打电话
[[result managedObjectContext] refreshObject:result mergeChanges:YES];
对象恢复到原始属性值。这意味着上下文就在那里,并且它与获取记录的上下文相同。这意味着新的属性值永远不会写入数据库。
一些代码
这是我正在研究所有这些东西的代码。在我的代码中还有其他地方我正在更改属性,但这些更改永远不会保存。
- (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]);
}
}
一转
如果我通过在上下文中插入新记录来创建新的结果对象,我可以设置该对象的属性并成功保存它们。在上面的代码中,我从另一个对象中获取对象作为多对多关联的成员。这是线索吗?
我正在为此烦恼。这里到底出了什么问题?
什么不是问题
-com.apple.CoreData.SQLDebug 1
记录 Core Data SQL 的参数,当我更新和保存对象的属性时没有记录 SQL 最佳答案
我不太明白你的说法
WCAAssessmentResult *result = [self currentResult];
事实上,如果您从一个对象访问一对多关系,您应该返回一个集合,而不是一个对象。无论如何,没有看到代码就很难说。您遇到的问题可能存在也可能不存在。
我宁愿在您的代码中使用类似于以下代码段的内容来访问属于多对多关系的对象。我假设
yourObject
是您用来访问 WCAAssessmentResult
的对象多对多关系中的对象,我称之为 results
.NSMutableSet *resultObjects = [yourObject mutableSetValueForKey:@"results"];
NSPredicate *predicate = ...
[resultObjects filterUsingPredicate:predicate];
for(WCAAssessmentResult *result in resultObjects){
// modify as needed the current result object
}
NSError *error = nil;
if (![managedObjectContext save:&error]) {
NSLog(@"save failed");
NSLog(@"%@",[error description]);
}
您是否验证过用于保存对象的 managedObjectContext 是否有效(非 nil)?
关于iphone - 核心数据不会持续更新数据库的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5628996/