2

我有Parent一个自定义类的实体,该类具有一个名为DerivedProperty.

的值DerivedProperty取决于Parent.IndependentProperty1_ IndependentProperty1_ DerivedProperty但是,与(称为)Parent具有一对多关系,并且还依赖于所有对象中的值。ChildchildrenDerivedPropertyIndependentProperty2ParentChild

因此IndependentProperty1,无论何时Parent任何对象发生变化,我都想通知任何也发生变化的IndependentProperty2观察者。ChildDerivedProperty

到目前为止,我已经到达了以下代码。唯一的问题是没有发出 KVO 通知,DerivedProperty因为如果我尝试这样做,objectContextDidChange:那么代码将结束在一个循环中。

- (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  ;
}

我确信我需要重新考虑我在这里的方法。我已经尝试使用 KVO 来观察IndependentProperty1IndependentProperty2多对多关系,但我似乎无法让它正常工作。如果派生属性不依赖于一对多关系,那么我确信我可以使用keyPathsForValuesAffectingValueForKey:,但当然这不适用于一对多关系。

如何使用依赖于一对多关系的 Core Data 瞬态派生属性获取 KVO 通知?

4

1 回答 1

3

首先,您正在访问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 正在使用瞬态属性直接访问该属性的 iVar。这有效地创建了两个 iVar,一个由 Core Data 维护,另一个由 OP 的代码维护。这导致了碰撞。

如果您使用的是瞬态属性,建议您按照建议将计算移动到另一种方法,并将访问器留给 Core Data。

于 2013-05-24T15:29:11.277 回答