获取核心数据中 NSManagedObject 的修改日期?
Posted
技术标签:
【中文标题】获取核心数据中 NSManagedObject 的修改日期?【英文标题】:Get modification date for NSManagedObject in Core Data? 【发布时间】:2011-08-14 08:58:04 【问题描述】:除了向我的核心数据存储中的每个实体添加 NSDate 属性之外,是否有一种编程方式来获取任何对象的修改日期?
【问题讨论】:
【参考方案1】:不,您必须添加日期并自行管理。您可以在托管对象中使用覆盖-willSave
来更新时间戳,但请阅读-willSave
上 NSManagedObject 的 API 文档,了解如何在不导致 willSave 循环的情况下进行更新(文档甚至讨论了更新时间戳的情况) .文档还提到使用NSManagedObjectContextWillSaveNotification
,但这可能比简单的检查设置时间戳更麻烦。
【讨论】:
Apple 提供了如何执行此操作的示例。阅读 -willSave:developer.apple.com/library/mac/#documentation/Cocoa/Reference/… 这里是更新的链接:developer.apple.com/documentation/coredata/nsmanagedobject/…【参考方案2】:我亲自检查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】:在 WWDC19 上是 announced Derived Attributes。
像这样的updated
属性由Core Data 自动更新:
注意:这可能会产生无效的Mapping Model。
【讨论】:
好消息!非常感谢!【参考方案4】:请注意,此解决方案假设我们有一个名为 dateUpated 的属性 在模型中。
而不是在单个对象上处理这个。我会通过通知处理这个问题。 Apple 文档也建议采用这种方式。
1。注册 NSManagedObjectContextWillSaveNotification 通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willSaveContext:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
2 为每个更新的对象在观察者方法中设置 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"];
【讨论】:
【参考方案5】:我发现此 Q/A 有助于开始为 Core Data 中的修改日期设置属性。在此过程中,我得出了一些可能也有帮助的提示:
(提示 1:避免 willSave 递归)
另一种避免 willSave 循环的方法是编写一个自定义例程来保存上下文,该例程遍历其 updatedObjects 查找具有 dateModified 属性的对象并进行设置。在该循环之后对commitEditing
和save
进行实际调用。根本不用为 willSave 烦恼。
(提示 2:实时更新 - 但无法使用撤消)
如果您需要实时更新以在表格中向用户显示修改日期,您还可以在您的 objectValueForTableColumn 委托方法( ios 的 willDisplayCell)。
在那里,测试该行的对象是否已更新,如果是,则设置 dateModified。我怀疑if (obj isUpdated)
支票非常昂贵。但请务必仅针对相关列执行此操作,以免不必要地重复。
返回用于列的任何字符串表示形式。为避免实际修改的时间与设置的日期之间出现明显差异,请仅显示日期,而不是时间。
这将导致 dateModified 在用户进行表格选择以及重新加载表格时更新。这并不完美——如果用户修改了表中未表示的属性,则在他们做出选择之前,该列不会更新。但它比实施广泛的 KVO 方案响应迅速且容易得多。
(您仍需要在保存例程中设置日期,以捕获对表不可见的修改。)
UNDO 复杂性:不幸的是,撤消管理器会将表委托方法对 dateModifed 的更改视为其自身的事件。 随后调用 undo 只是一次又一次地撤消对 dateModified 的最后更改。我尝试通过添加一个跟踪器并检查一个非空的 changedValues 字典来克服这个问题,以确保 dateModified 仅在预保存时设置一次。这适用于撤消删除,但不适用于常规编辑。所以没有快速的方法来完成 dateModified 预保存的实时更新。
【讨论】:
提示 0:Apple 在文档中讲述了如何避免 willSave 递归。 developer.apple.com/library/mac/#documentation/Cocoa/Reference/…【参考方案6】:如果有人想在 Swift 中以简单的方式做到这一点:我写了 a blog post 一个简单的 UpdateListener
类来更新所有 updateDate
和 insertDate
属性。您可以在this gist 中找到整个课程。您所要做的就是在您的应用程序委托的application(:didFinishLaunchingWithOptions:)
方法中调用UpdateListener.setupSharedInstance()
。
【讨论】:
【参考方案7】:Ben Affleck 答案的 Swift 版本
public override func willSave()
super.willSave()
if !isDeleted, changedValues()["updatedAt"] == nil
self.setValue(Date(), forKey: "updatedAt")
【讨论】:
以上是关于获取核心数据中 NSManagedObject 的修改日期?的主要内容,如果未能解决你的问题,请参考以下文章
核心数据。对大尺寸 NSManagedObject 的 NSMutableSet 进行排序