【问题标题】:Get modification date for NSManagedObject in Core Data?获取核心数据中 NSManagedObject 的修改日期?
【发布时间】:2011-08-14 08:58:04
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    【解决方案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 属性的对象并进行设置。在该循环之后对commitEditingsave 进行实际调用。根本不用为 willSave 烦恼。

        (提示 2:实时更新 - 但无法使用撤消)

        • 如果您需要实时更新以在表格中向用户显示修改日期,您还可以在您的 objectValueForTableColumn 委托方法( iOS 的 willDisplayCell)。

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

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

        • 这将导致 dateModified 在用户进行表格选择以及重新加载表格时更新。这并不完美——如果用户修改了表中未表示的属性,则在他们做出选择之前,该列不会更新。但它比实施广泛的 KVO 方案响应迅速且容易得多。

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

        • UNDO 复杂性:不幸的是,撤消管理器会将表委托方法对 dateModifed 的更改视为其自身的事件。 随后调用 undo 只是一次又一次地撤消对 dateModified 的最后更改。我尝试通过添加一个跟踪器并检查一个非空的 changedValues 字典来克服这个问题,以确保 dateModified 仅在预保存时设置一次。这适用于撤消删除,但不适用于常规编辑。所以没有快速的方法来完成 dateModified 预保存的实时更新。

        【讨论】:

        【解决方案6】:

        如果有人想在 Swift 中以简单的方式做到这一点:我写了 a blog post 一个简单的 UpdateListener 类来更新所有 updateDateinsertDate 属性。您可以在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")
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多