NSManagedObject timeStamp更新

时间:2014-01-24 10:22:19

标签: ios nsmanagedobject key-value-observing

我想跟踪NSManagedObject属性的更改,以保持NSData * lastUpdate属性“最新”

当NSManagedObject更改其属性时,有几种方法可以获得Notified

予。首先是覆盖要跟踪的所有属性的setter方法。这在NSManaged对象中非常复杂 - 请检查here

II。第二个可能是一个好的。您可以覆盖“didChangeValueForKey”方法,该方法在每次更改属性时都会调用。

-(void)didChangeValueForKey:(NSString *)key{
    [super didChangeValueForKey:key];
    NSLog(@"Value for key:%@ has changed", key);
}

不幸的是,由于文档说明了......:

,我们不应该覆盖此方法
  

“你不能覆盖这种方法。”

III。键值观察引导我们回到IInd方法,重写“didChangeValueForKey”。

UPD。 IV。我试图覆盖-willSave方法

-(void)willSave{
   NSArray *observedKeys = @[@"name", @"imageType"];
   NSDictionary * changesALL = self.changedValues;
   for (id key in changesALL){
       if ([observedKeys containsObject:key]){
           self.lastUpdate = [NSDate date];
           NSLog(@"updated For key: %@", key);
        }
    }
}

这导致了不定式循环,文档中对此进行了描述。 (这里描述了正确的方法,所以我已经回答了这个问题)

  

如果要更新持久属性值,通常应在进行更改之前使用现有值测试任何新值的相等性>。如果使用标准访问器方法更改属性>值,Core Data将观察结果更改>通知,因此在保存对象的托管对象>上下文之前再次调用willSave。如果你继续修改willSave中的值,willSave将继续被称为>直到你的程序崩溃。

     

例如,如果您设置了上次修改的时间戳,则应检查是否>先前在同一个保存操作中设置了它,或者现有时间戳是否小于>当前时间的小增量。通常,最好为所有正在保存的对象计算时间戳>(例如,响应> NSManagedObjectContextWillSaveNotification)。

3 个答案:

答案 0 :(得分:4)

适合您的用例的解决方案,以覆盖willSave方法并使用它来设置新的lastUpdated值。在将脏对象保存到上下文之前,会自动调用此方法。


如果您需要验证哪些是脏的,您可以使用changedValues属性的内容。

答案 1 :(得分:2)

因此,毕竟我发现跟踪托管对象更改的最佳解决方案是注册NSManagedObjectContextWillSaveNotification,并在托管对象上下文中设置所有更新和插入对象的时间戳。注册的方法可能如下所示:

-(void)contextWillSave:(NSNotification *)notify
{
NSManagedObjectContext *context = [notify object];
NSDate *dateOfTheLastModification = [NSDate date];
for (NSManagedObject *obj in [context insertedObjects]) {
    [obj setValue:dateOfTheLastModification forKey:@"lastUpdate"];
}
for (NSManagedObject *obj in [context updatedObjects]) {
    [obj setValue:dateOfTheLastModification forKey:@"lastUpdate"];
}
}

这假定您的所有实体都具有lastModifiedDate属性,否则您必须检查对象的类。

答案 2 :(得分:1)

为了避免无限循环,试试这个魔法:

- (void)willSave{
    if(![self.changedValues objectForKey:@"localModificationDate"]){
        self.localModificationDate = [NSDate date];
    }
    else{
        [super willSave];
    }
}

一旦设置了修改日期,它就不会再为当前保存设置它。有一个副作用,如果保存失败并再次成功保存,我认为日期将是上一次保存尝试的日期。

如果您在每次编辑后保存上下文,这很好,但通常的核心数据设计只能在应用程序暂停或长时间后保存。因此,在此之前可能会需要lastUpdate,并且它还没有获得新值。

相关问题