NSManagedObject 时间戳更新
Posted
技术标签:
【中文标题】NSManagedObject 时间戳更新【英文标题】:NSManagedObject timeStamp update 【发布时间】:2014-01-24 10:22:19 【问题描述】:我想跟踪 NSManagedObject 属性的变化,以使 NSData *lastUpdate 属性保持“最新”
有几种方法可以在 NSManagedObject 更改其属性时获得通知
我。首先是覆盖所有要跟踪的属性的 setter 方法。这在 NSManaged 对象中相当复杂 - 检查它here
二。第二个可能是一个很好的。您可以覆盖在每次属性更改时调用的“didChangeValueForKey”方法。
-(void)didChangeValueForKey:(NSString *)key
[super didChangeValueForKey:key];
NSLog(@"Value for key:%@ has changed", key);
不幸的是,我们不应该重写这个方法,因为文档说...:
“你不能重写这个方法。”
三。键值观察让我们回到 IInd 方法,覆盖“didChangeValueForKey”。
更新。 四。我试图覆盖 -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)。
【问题讨论】:
您要跟踪什么,为什么?这决定了适当的方式来做到这一点...... 我必须跟踪 NSManaged 对象的 lastUpdate 【参考方案1】:适合您的用例的解决方案是覆盖willSave
方法并使用它来设置新的lastUpdated
值。在将脏对象保存到上下文之前,会自动调用此方法。
如果您需要验证什么是脏的,您可以使用changedValues
属性的内容。
【讨论】:
不错,但如果我不想处理其中一项属性更改怎么办? 您可以检查 changedValues NSDictionary 并在这种情况下跳过更新时间戳。 如果您这样做,您可能希望使用setPrimitiveValue
方法来避免此更改触发另一个willChange
根据Apple 的文档调用:developer.apple.com/library/mac/Documentation/Cocoa/Reference/…【参考方案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 属性,否则您必须检查对象的类。
【讨论】:
【参考方案3】:为了避免无限循环,试试这个魔法:
- (void)willSave
if(![self.changedValues objectForKey:@"localModificationDate"])
self.localModificationDate = [NSDate date];
else
[super willSave];
一旦设置了修改日期,它将不会为当前保存再次设置它。有一个副作用,如果保存失败并且您再次成功保存,我认为日期将是上次保存尝试的日期。
如果您在每次编辑后保存上下文,这很好,但核心数据的通常设计是仅在应用挂起或长时间后保存。所以很可能在此之前某些东西需要 lastUpdate 并且它还没有新的值。
【讨论】:
以上是关于NSManagedObject 时间戳更新的主要内容,如果未能解决你的问题,请参考以下文章
获取核心数据中 NSManagedObject 的修改日期?
使用 touch() 更新 laravel 中自定义时间戳字段的时间戳