除了向我的核心数据存储中的每个实体添加NSDate属性之外,是否有一种编程方式来获取任何对象的修改日期?
答案 0 :(得分:21)
不,您必须添加日期并自行管理。您可以在托管对象中使用覆盖-willSave
来更新时间戳,但是在-willSave
上阅读NSManagedObject的API文档,了解如何在不引起willSave循环的情况下进行更新(文档甚至讨论了更新时间戳)。文档还提到使用NSManagedObjectContextWillSaveNotification
,但设置起来可能比简单检查更难以设置时间戳太快。
答案 1 :(得分:6)
请注意此解决方案假设我们有一个名为dateUpated的属性 在模特中。
而不是在单个对象处理此问题。我会通过通知来处理这个问题。 Apple文档也提供了这种方式。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willSaveContext:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
- (void)willSaveContext:(NSNotification *)notification{
NSManagedObjectContext *context = [notification object];
NSSet *updatedObject = [context updatedObjects];
for (NSManagedObject *managedObject in [updatedObject allObjects]) {
if ([[managedObject.entity propertiesByName] objectForKey:@"dateUpdated"]) {
[managedObject setValue:[NSDate date] forKey:@"dateUpdated"];
}
}
}
答案 2 :(得分:6)
我亲自检查updatedAt
是否被修改,如果是,那么我不再触摸它了。这样我就打破了willSave
循环。
- (void)awakeFromInsert {
[super awakeFromInsert];
self.primitiveUpdatedAt = [NSDate date];
}
- (void)willSave {
[super willSave];
if(![self isDeleted] && self.changedValues[@"updatedAt"] == nil) {
self.updatedAt = [NSDate date];
}
}
答案 3 :(得分:2)
我发现此Q / A有助于开始设置Core Data中修改日期的属性。在这个过程中,我得到了一些可能也有帮助的提示:
(提示1:避免使用willSave递归)
commitEditing
和save
进行实际调用。不要理会使用willSave。(提示2:实时更新 - 但不适用于撤销)
如果您需要实时更新以在表格中显示修改给用户的日期,您还可以在objectValueForTableColumn委托方法中为日期修改列的开关案例(或其他)中设置dateModified( willDisplayCell for iOS)。
在那里,测试该行的对象是否已更新,如果是,则设置dateModified。我怀疑if (obj isUpdated)
检查非常昂贵。但请务必仅针对相关列进行此操作,以免不必要地重复此操作。
返回您用于列的任何字符串表示形式。为避免实际修改时间与设定日期之间存在明显差异,请仅显示日期,而不是时间。
每当用户选择表格时,以及重新加载表格时,都会更新dateModified。这并不完美 - 如果用户修改了表中未表示的属性,则列在进行选择之前不会更新。但它比实施广泛的KVO方案具有合理的响应性和容易性。
(您仍然需要在保存例程中设置日期,以捕获对表不可见的修改。)
UNDO COMPLICATION:不幸的是,撤消管理器会将表委托方法的更改视为dateModifed自身的事件。 随后调用撤消只是撤消对dateModified的最后一次更改 - 一遍又一遍。我尝试通过添加跟踪器和检查非空的changedValues字典来确保dateModified仅在预保存时设置一次。这有助于撤消删除,但不适用于常规编辑。因此,没有快速的方法来完成dateModified pre-save的实时更新。
答案 4 :(得分:2)
答案 5 :(得分:0)
如果有人想在Swift中轻松实现这一点:我写了一篇关于简单UpdateListener
类的a blog post来更新所有updateDate
和insertDate
属性。您可以在this gist中找到整个班级。您所要做的就是在应用程序代表的UpdateListener.setupSharedInstance()
方法中调用application(:didFinishLaunchingWithOptions:)
。
答案 6 :(得分:0)
本阿弗莱克答案的 Swift 版本
public override func willSave() {
super.willSave()
if !isDeleted, changedValues()["updatedAt"] == nil {
self.setValue(Date(), forKey: "updatedAt")
}
}