我有Parent
个实体,其自定义类具有名为DerivedProperty
的瞬态和派生(只读)属性。
DerivedProperty
的值取决于Parent.IndependentProperty1
的值,因此每当IndependentProperty1
发生变化时,DerivedProperty
的值都会发生变化。但是,Parent
与Child
(称为children
)之间存在多对多关系,而DerivedProperty
也与所有{IndependentProperty2
的值Parent
有关。 1}}的{{1}}个对象。
因此,只要Child
IndependentProperty1
Parent
个IndependentProperty2
对象发生变化,我就会通知任何观察者Child
也发生了变化
到目前为止,我已经得到了以下代码。唯一的问题是没有为DerivedProperty
发出KVO通知,因为如果我尝试在DerivedProperty
中执行此操作,那么代码将以循环结束。
objectContextDidChange:
我确信我需要彻底重新考虑我的做法。我已经尝试使用KVO来观察多对多关系中的- (void) awakeFromInsert
{
[super awakeFromInsert];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectContextDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.managedObjectContext];
}
- (void) awakeFromFetch
{
[super awakeFromFetch];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectContextDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.managedObjectContext];
}
- (void) objectContextDidChange: (NSNotification *) notification
{
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
if ([updatedObjects containsObject:self] || [updatedObjects intersectsSet:self.children])
{
//clear caches
_derivedProperty = nil;
}
}
- (void) didTurnIntoFault
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (NSString *) DerivedProperty
{
if (_derivedProperty == nil)
{
_derivedProperty = [self someExpensiveCalculation];
}
return _derivedProperty ;
}
和IndependentProperty1
,但我似乎无法让它正常工作。如果派生属性不依赖于多对多关系,那么我确信我可以使用IndependentProperty2
,但当然这对多对多关系无效。
如何使用依赖于多对多关系的Core Data瞬态衍生属性获取KVO通知?
答案 0 :(得分:2)
首先,您正在DerivedProperty
方法中访问-objectContextDidChange:
的ivar,并将KVO通知短路。您应该在内部以读/写方式重新实现该属性并使用生成器访问器。
其次,NSManagedObject
的子类默认关闭自动KVO。这是Core Data架构的一部分。因此,如果您不打算使用访问者,您可能希望自己触发通知:
- (void) objectContextDidChange: (NSNotification *) notification
{
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
if ([updatedObjects containsObject:self] || [updatedObjects intersectsSet:self.children]) {
//clear caches
[self willChangeValueForKey:@"derivedProperty"];
_derivedProperty = nil;
[self didChangeValueForKey:@"derivedProperty"];
}
}
在这种情况下,OP使用瞬态属性 AND 直接访问属性的iVar。这有效地创建了两个iVar,一个由Core Data维护,另一个由OP的代码维护。这导致了碰撞。
如果您使用的是瞬态属性,建议您按照建议将计算移动到另一个方法,并将访问者留给核心数据。