2

Parentと呼ばれる一時的な派生 (読み取り専用) プロパティを持つカスタム クラスを持つエンティティがありますDerivedProperty

の値は の値にDerivedProperty依存するParent.IndependentProperty1ためIndependentProperty1、変化すると の値もDerivedProperty変化します。ただし、は( と呼ばれる) とParent対多関係にあり、すべての のオブジェクトのの値にも依存しています。ChildchildrenDerivedPropertyIndependentProperty2ParentChild

そのため、オブジェクトが変更されるたびIndependentProperty1に、Parent変更されたオブザーバーにも通知したいと思います。IndependentProperty2ChildDerivedProperty

これまでのところ、次のコードに到達しました。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  ;
}

ここでのアプローチを完全に再考する必要があると確信しています。KVO を使用して対多関係を観察しようとしましたIndependentProperty1IndependentProperty2、正しく機能していないようです。派生プロパティが対多関係に依存していない場合は、それをそのまま使用できると確信していますkeyPathsForValuesAffectingValueForKey:が、もちろんそれは対多関係では機能しません。

対多関係に依存するコア データの一時的な派生プロパティで動作する KVO 通知を取得するにはどうすればよいですか?

4

1 に答える 1

3

まず、メソッドで ivar for にアクセスしていて、それがKVO 通知を短絡DerivedPropertyさせます。-objectContextDidChange:プロパティを内部で読み取り/書き込みとして再実装し、ジェネレーターアクセサーを使用する必要があります。

次に、 のサブクラスで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に直接アクセスしていました。これにより、2 つの iVar が効果的に作成されました。1 つは Core Data によって維持され、もう 1 つは OP のコードによって維持されます。これが衝突の原因でした。

一時的なプロパティを使用している場合は、提案されているように計算を別の方法に移動し、アクセサーを Core Data のままにすることをお勧めします。

于 2013-05-24T15:29:11.277 に答える