当父实体中的任何一个关系对象发生变化时,是否可以在父实体中接收回调或通知?当实体的属性发生变化时,这很有用。以下方法......
- (void)didChangeValueForKey:(NSString *)key
。但是,当其中一个关系中的属性发生更改时,不会调用此方法。
我要做的是当我的父实体中的任何一个属性或关系对象发生更改时,更新timeStamp属性。
答案 0 :(得分:5)
父实体可以将自己设置为关系的观察者,并在关系发生变化时收到通知。但是,只有在实际关系(添加或删除子项)发生时才会触发。
观察特定的儿童实体要复杂得多。有几种方法可以解决这个问题:
NSManagedObjectContextDidSaveNotification
并查看其中的任何一个孩子是否在保存可能还有其他解决方案,但我推荐#2。设置非常简单,性能影响非常小。
答案 1 :(得分:1)
在另一个答案中,我发现1,2和3效率太低。特别是2和“看着它的孩子的父母”博客文章中的例子。我的问题是每个父母都必须回应上下文通知,基本上每个对象都被保存(如果它是孩子)(更不用说在这种情况下ContextDidSave更合适!)。相反,我会提出一个选项4:
我的解决方案效率更高,感觉更加面向对象,因为正在变化的对象正在响应自己的变化。要实现这一点,请在子对象中使用:
-(void)didSave{
[super didSave];
// notify that the parent has changed.
[[NSNotificationCenter defaultCenter] postNotificationName:NSManagedObjectContextObjectsDidChangeNotification
object:self.managedObjectContext
userInfo:@{NSUpdatedObjectsKey : [NSSet setWithObject:self.parent]}];;
}
要更新父时间戳,我一直在使用的以下简洁解决方案(second last post)可能有所帮助,例如:在父使用中:
- (void) awakeFromInsert
{
[super awakeFromInsert];
// set the default dates
NSDate* date = [NSDate date];
self.timestamp = date;
//allow any future modifications to change the timestamp
_finishedStartup = YES;
}
- (void) awakeFromFetch
{
[super awakeFromFetch];
// we should already have creation and modified dates.
_finishedStartup = YES;
}
- (void) didChangeValueForKey: (NSString *) thisKey
{
[super didChangeValueForKey: thisKey];
if(![thisKey isEqualToString:@"timestamp"] && // prevent infinite loop
![self isFault] &&
![[[self managedObjectContext] undoManager] isUndoing] &&
_finishedStartup) // ensures we arent being called by the object being loaded from fetched data.
{
self.timestamp = [NSDate date];
}
}