1

Core Data オブジェクトにリンクされた NSArrayController があり、コンテンツの自動再配置に設定され、述語によってフィルター処理されています。関係を無効にして別の関係を割り当てようとするまでは、すべて問題ありません。その時点で、アプリケーションがクラッシュし、次のエラーが表示されます。

オブジェクトからキー パス「career.type」のオブザーバーを削除できません。おそらく、適切な KVO 通知が送信されずにキー「career」の値が変更されたためです。Person クラスの KVO 準拠を確認します。

スヌーピングから、NSArrayController をコンテンツの自動再配置に設定すると、この問題が発生するようです。しかし、NSArrayController を手動で再配置する必要なく、問題を解決しようとしています。エラーを引き起こしている疑似コードは次のとおりです。

object.career = nil;
object.field = (Field *)item;

私の NSArrayController が使用している述語は次のとおりです。

(career != NIL && career == %@) || (field != NIL && field == %@)

両方のインスタンスの %@ は CoreData オブジェクトです。

基本的に、NSArrayController には object.career.type にオブザーバーが設定されているように見えますが、関係を無効にすると、そのオブザーバーが自動的に削除されるときに問題が発生します。だから、私はこれについて間違った方法をとっているのかと思っていますか?オブジェクトのコピーを取得し、MOC から削除して、キャリアを nil に設定し、それに応じてフィールドを設定して再挿入する必要がありますか?

型が無効化されたことをオブザーバーに正しく通知するにはどうすればよいですか? ここで言及されているすべての属性と関係は、通常の KVO 準拠の getter/setter を使用していることに注意してください。

4

1 に答える 1

4

リンゴのドキュメントから

障害とKVO通知

Core Dataがオブジェクトを障害に変えると、Key-Value監視(KVO)変更通知(Key-Value監視プログラミングガイドを参照)がオブジェクトのプロパティに対して送信されます。フォールトに変換されたオブジェクトのプロパティを監視していて、その後フォールトが認識された場合、値が実際には変更されていないプロパティの変更通知を受け取ります。

値はあなたの観点からは意味的に変化していませんが、オブジェクトが具体化されるにつれて、メモリ内のリテラルバイトが変化しています。Key-Value監視メカニズムでは、ポインター比較の観点から考慮されるように、値が変更されるたびにCoreDataが通知を発行する必要があります。KVOは、キーパスと依存オブジェクト間の変更を追跡するためにこれらの通知を必要とします。


したがって、基本的には、変更がない場合でも変更があることを通知する通知が届きます。したがって、オブジェクトが障害になったかどうかを確認する必要があります。次に、古いオブザーバーを削除し、同じパスに新しいオブザーバーを追加します...

私にとってこれはうまくいきました(サンプルコード):

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

    if ([keyPath isEqualToString:@"pageIndex"]) {

        // basically remove the observer from the fault object and assign the new
        if([object isFault]) {
            [object removeObserver:self forKeyPath:@"pageIndex"];
            [the_current_instance_returned_by_core_data addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionOld context:NULL];
        } 

        // do whatever you want to do on change...

    }
}
于 2011-05-20T07:49:48.747 に答える