获取Core Data中NSManagedObject的修改日期?

时间:2011-04-28 03:35:00

标签: iphone ios core-data nsmanagedobject last-modified

除了向我的核心数据存储中的每个实体添加NSDate属性之外,是否有一种编程方式来获取任何对象的修改日期?

7 个答案:

答案 0 :(得分:21)

不,您必须添加日期并自行管理。您可以在托管对象中使用覆盖-willSave来更新时间戳,但是在-willSave上阅读NSManagedObject的API文档,了解如何在不引起willSave循环的情况下进行更新(文档甚至讨论了更新时间戳)。文档还提到使用NSManagedObjectContextWillSaveNotification,但设置起来可能比简单检查更难以设置时间戳太快。

答案 1 :(得分:6)

  

请注意此解决方案假设我们有一个名为dateUpated的属性   在模特中。

而不是在单个对象处理此问题。我会通过通知来处理这个问题。 Apple文档也提供了这种方式。

1。注册NSManagedObjectContextWillSaveNotification通知

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(willSaveContext:)         
                                             name:NSManagedObjectContextWillSaveNotification 
                                           object:nil];

2为每个更新的对象在observer方法中设置updatedDate的属性。

- (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递归)

  • 避免使用willSave循环的另一种方法是编写一个自定义例程来保存上下文,该上下文遍历其updatedObjects,查找具有dateModified属性并设置它的那些。在该循环之后对commitEditingsave进行实际调用。不要理会使用willSave。

(提示2:实时更新 - 但不适用于撤销)

  • 如果您需要实时更新以在表格中显示修改给用户的日期,您还可以在objectValueForTableColumn委托方法中为日期修改列的开关案例(或其他)中设置dateModified( willDisplayCell for iOS)。

  • 在那里,测试该行的对象是否已更新,如果是,则设置dateModified。我怀疑if (obj isUpdated)检查非常昂贵。但请务必仅针对相关列进行此操作,以免不必要地重复此操作。

  • 返回您用于列的任何字符串表示形式。为避免实际修改时间与设定日期之间存在明显差异,请仅显示日期,而不是时间。

  • 每当用户选择表格时,以及重新加载表格时,都会更新dateModified。这并不完美 - 如果用户修改了表中未表示的属性,则列在进行选择之前不会更新。但它比实施广泛的KVO方案具有合理的响应性和容易性。

  • (您仍然需要在保存例程中设置日期,以捕获对表不可见的修改。)

  • UNDO COMPLICATION:不幸的是,撤消管理器会将表委托方法的更改视为dateModifed自身的事件。 随后调用撤消只是撤消对dateModified的最后一次更改 - 一遍又一遍。我尝试通过添加跟踪器和检查非空的changedValues字典来确保dateModified仅在预保存时设置一次。这有助于撤消删除,但不适用于常规编辑。因此,没有快速的方法来完成dateModified pre-save的实时更新。

答案 4 :(得分:2)

在WWDC19上是announced Derived Attributes

Core Data会自动更新一个updated属性,

Core Derived Attribute screenshot

答案 5 :(得分:0)

如果有人想在Swift中轻松实现这一点:我写了一篇关于简单UpdateListener类的a blog post来更新所有updateDateinsertDate属性。您可以在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")
    }
}