核心数据:setPrimitiveValue 和保存更改
Posted
技术标签:
【中文标题】核心数据:setPrimitiveValue 和保存更改【英文标题】:Core Data: setPrimitiveValue and saving changes 【发布时间】:2011-06-01 17:42:01 【问题描述】:在 Core Data 中,当使用 setPrimitiveValue 与对象的常规访问器方法进行更改时,是否有一些技巧可以保存对托管对象属性的更改?
为了避免触发我的 FRC 的通知方法(controllerWillChangeContent、controllerDidChangeObject 等),我已切换到在一些场景中使用 setPrimitiveValue 和 setPrimitiveAttributeName。在这两种情况下,在对核心数据对象进行更改并保存托管对象上下文之后,这些更改看起来就像是已经做出的(即我可以通过 NSLog 看到更改)但它们实际上已经丢失了(即如果我在模拟器并重新运行它,FRC重新加载,我以为我改变的属性消失了)。
保存代码是从 Apple 示例中复制的,我的 Core Data 实体的托管对象类是由 Xcode 生成的。我从 Apple 和本网站上读到的所有内容都表明这是对 setPrimitive 方法的有效使用,尽管我承认我对这些 setPrimitive 函数的真正工作原理缺乏一些了解......
代码:
// header file for Managed Object sub class generated by xcode from my core data entity:
#import <CoreData/CoreData.h>
@interface PlannedItem : NSManagedObject
@property (nonatomic, retain) NSNumber * ptType;
@property (nonatomic, retain) NSNumber * whenOrder;
@end
// .m file for Managed Object subclass
#import "PlannedItem.h"
@implementation PlannedItem
@dynamic ptType;
@dynamic whenOrder;
@end
// trying to use setPrimitiveValue or even setPrimitiveWhenOrder to modify
// this is in my view controller
// p is a pointer to PlannedItem
int oldOrder = [p.whenOrder intValue];
[p setPrimitiveValue:[NSNumber numberWithInt:(oldOrder +1)] forKey:@"whenOrder"];
// later on in same method, save is executed.
if (![[self managedObjectContext] save:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
NSLog(@"Saved");
感谢任何提示
【问题讨论】:
hmmmmm.... 看起来 willChangeValueForKey 和 didChangeValueForKey 是我正在寻找的。我还不能发布答案,但如果我没有碰巧遇到更好的建议,我稍后会发布...... 我收回了 - willChangeValueForKey 和 didChangeValueForKey 有帮助,但它们会导致 FRC 再次向委托调用内容更改通知。我想我希望我的 FRC 和我使用 setPrimtiveValue 所做的更改的所有内容都是最新的,但我也不希望在这种情况下运行那些内容更改通知方法。我想我不能同时拥有它,可以吗? KVO 对 willChange 等的调用是 Core Data 在此之后开始起作用的必要条件。 【参考方案1】:如果您不希望通知处理程序中的代码执行(顺便说一句,您为什么要这样做?),禁用 that 可能更容易,而不是完全避免通知。另外,请记住,Core Data 使用这些通知来更新您的关系并在您进行更改时保持模型的一致性。
在您的视图控制器中,设置一个布尔值并根据您是否需要执行通知处理程序代码进行设置。然后,在您的处理程序中检查该标志,例如:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
if (notificationIgnored)
return;
// rest of the code...
【讨论】:
我不希望代码通知处理程序执行的原因是被更新的属性只是一个由 fetchedResultsController 支持的 UITableView 的显示顺序。 所以当我添加一个对象时,我现在更新所有后续行的显示顺序。使用您描述的标志应该可以,但是对我来说,它并不是一个非常干净的解决方案,它给了我奇怪的错误。我希望我可以使用 setPrimitiveValue 来避免那些额外的更新首先触发处理程序。唉,octy 描述的解决方案看起来是最好的选择。以上是关于核心数据:setPrimitiveValue 和保存更改的主要内容,如果未能解决你的问题,请参考以下文章