gpt4 book ai didi

ios - 核心数据 : Emitting KVO notifications for transient, 派生属性

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:09:59 27 4
gpt4 key购买 nike

我有一个带有自定义类的 Parent 实体,该类具有名为 DerivedProperty 的 transient 派生(只读)属性。

DerivedProperty 的值取决于 Parent.IndependentProperty1 的值,因此每当 IndependentProperty1 更改时,DerivedProperty 的值 会改变。但是,ParentChild(称为 children)具有一对多关系,并且 DerivedProperty 也依赖于IndependentProperty2 在所有 ParentChild 对象中的值。

因此,每当 ParentIndependentProperty1 或任何 Child 对象的 IndependentProperty2 发生变化时,我想通知所有观察者 DerivedProperty 也已更改。

到目前为止,我已经得到了以下代码。唯一的问题是没有为 DerivedProperty 发出 KVO 通知,因为如果我尝试在 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: 但当然这在一对多关系中不起作用。

如何让 KVO 通知与依赖于一对多关系的 Core Data transient 派生属性一起使用?

最佳答案

首先,您在 -objectContextDidChange: 方法中访问 DerivedProperty 的 ivar,并使 KVO 通知短路。您真的应该在内部将该属性重新实现为读/写并使用生成器访问器。

其次,NSManagedObject 的子类默认关闭自动 KVO。这是核心数据架构的一部分。因此,如果您不打算使用访问器,您可能希望自己触发通知:

- (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 使用 transient 属性 AND 直接访问该属性的 iVar。这有效地创建了两个 iVar,一个由 Core Data 维护,另一个由 OP 代码维护。这引起了碰撞。

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

关于ios - 核心数据 : Emitting KVO notifications for transient, 派生属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16738126/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com