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

问题描述 投票:15回答:6

除了在我的Core Data存储中为每个实体添加一个NSDate属性外,是否有一种程序化的方法来获取任何对象的修改日期?

iphone ios core-data nsmanagedobject last-modified
6个回答
21
投票

没有,你必须自己添加一个日期并管理它。 您可以使用覆盖 -willSave 中更新时间戳,但请阅读NSManagedObject的API文档。-willSave 如何在更新时不引起willSave循环(文档中甚至提到了更新时间戳的情况)。 文档中还提到了在更新时间戳的情况下使用 NSManagedObjectContextWillSaveNotification但这可能比简单的检查时间戳不要设置得太快更麻烦。


8
投票

我个人会检查 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];
    }
}

7
投票

请注意,这个解决方案假设我们在模型中有一个叫做dateUpated的属性。

而不是在单个对象上处理这个问题。我会通过一个通知来处理这个问题。苹果文档也建议这样做。

1. 注册NSManagedObjectContextWillSaveNotification通知。

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

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

- (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
投票

我发现这个QA对开始在Core Data中设置修改日期的属性很有帮助。在这个过程中,我得出了几个小技巧,可能也会有帮助。

(技巧1:避免willSave递归)

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

(提示2:实时更新--但对undo无效)

  • 如果你需要实时更新,以便在表中向用户显示修改的日期,你也可以在你的objectValueForTableColumn委托方法(iOS的willDisplayCell)中为日期修改的列设置switch-case(或其他什么)中的dateModified。

  • 在那里,测试该行的对象是否为Updated,如果是,则设置dateModified。我怀疑 if (obj isUpdated) 检查是非常昂贵的。但一定要只对相关的列进行检查,以免不必要的重复。

  • 返回你对该列使用的任何字符串表示。为了避免实际修改的时间和设置的日期之间出现明显的差异,只显示日期,而不是时间。

  • 这将导致每当用户进行表选择时,以及当表被重新加载时,dateModified都会被更新。这并不完美--如果用户修改了一个没有在表中显示的属性,那么在用户进行选择之前,该列不会更新。但这是合理的响应,比实现一个广泛的KVO方案要简单得多。

  • (你还是要在保存例程中设置日期,以捕捉对表不可见的修改。)

  • 撤消复杂:不幸的是,撤消管理器会将表委托方法对dateModifed的修改视为一个事件本身。随后调用undo只是简单地撤销上次对dateModified的修改--一遍又一遍。我试着通过添加跟踪器和检查非空的 changedValues 字典来克服这个问题,以确保 dateModified 只在保存前设置一次。这对撤销删除有效,但对常规编辑无效。所以没有快速的方法来实现保存前dateModified的实时更新。


1
投票

在WWDC19上,它是 公布 衍生属性.

updated 像这样的属性是由Core Data自动更新的。

Core Derived Attribute screenshot


0
投票

如果有人想在Swift中找到一个简单的方法, 我写了 博文 简陋 UpdateListener 类来更新所有的 updateDateinsertDate 属性。你可以在 此要旨. 你所要做的就是打电话 UpdateListener.setupSharedInstance()application(:didFinishLaunchingWithOptions:) 的方法。

© www.soinside.com 2019 - 2024. All rights reserved.