3

Core Data で関連するエンティティをプリフェッチしようとすると、KVO 例外がスローされるという問題があります。私には意味がなく、単純化されたプロジェクトで動作を複製することはできません。私は10.8をターゲットにしており、ARCを使用しています。

私のデータは音楽ライブラリをモデル化しており、関心のある 3 つのエンティティTrack、 、Artist、および がありAlbumます。トラックには 1 人のアーティストと 1 つのアルバムが含まれ、アルバムには 1 つのアーティストが含まれます。MyAlbumArtistobject は名前で一意です (ストア内で特定の名前を持つアーティストは 1 人だけです)。

次のフィールドを含むトラックのリストを表示したい: タイトル、アーティスト名、アルバム.タイトル。これは、NSTableView のTrackエンティティとバインディングに NSArrayController を使用して簡単に実現できます。

ただし、アーティストとアルバムの関係を使用することがわかっているので、トラックが読み込まれるときにそれらをプリフェッチしたいと思います。次のようなカスタム performFetch: メソッドを使用して NSArrayController サブクラスを作成しました。

- (BOOL) fetchWithRequest:(NSFetchRequest *)fetchRequest merge:(BOOL)merge error:(NSError *__autoreleasing *)error
{
    NSEntityDescription *entityDescription = [Track entityInManagedObjectContext:[self managedObjectContext]];
    fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entityDescription];
    [fetchRequest setRelationshipKeyPathsForPrefetching:@[@"album", @"artist"]];

    return [super fetchWithRequest:fetchRequest merge:merge error:error];
}

IB の NSArrayController のクラスを自分のサブクラスに設定したところ、UI の遅延がなくなることを期待していました (スクロールごとに障害が発生していました)。ただし、例外がスローされます。

2013-01-01 10:48:06.965 XXX[10593:303] からのキー パス「artist.name」のオブザーバーを更新できません。おそらく、キー「artist」の値が適切な KVO 通知なしで変更されたためです。送信済。Track クラスの KVO 準拠を確認します。

カスタムNSArrayControllerサブクラスの前は、すべてが正しく機能していました。サブクラスのsetRelationshipKeyPathsForPrefetching行をコメントアウトするだけで、すべてが再び機能します。NSArrayControllerプリフェッチと KVO の間のリンクが何であるかを判断できません。Core Data の専門家で、これまでにこのようなことを見たことがありますか?

4

1 に答える 1

1

私は本質的に同じ問題に遭遇しました。これは、解決中に学んだことです。

NSArrayController はsetRelationshipKeyPathsForPrefetching:、すべての状況でうまく機能しないようです。子コンテキストでプリフェッチ リクエストを実行していたところ、親コンテキストの KVC が壊れてしまいましたNSArrayController。これは、意図しない動作であると考えられます。いずれにせよ、私がそれを修正した方法は、「古い」スタイル(10.4)のプリフェッチを使用することでした。これは次のようになります...

NSFetchRequest *trackReq = [[NSFetchRequest alloc] initWithEntityName:@"Track"];
NSArray *fetchedTracks = [context executeFetchRequest:trackReq error:&error];

NSFetchRequest *batchFaultReq = [[NSFetchRequest alloc] initWithEntityName:@"Artist"];
[batchFaultReq setPredicate:[NSPredicate predicateWithFormat:@"SELF.tracks in %@", fetchedTracks];
NSArray *faultedItems = [context executeFetchRequest:batchFaultReq error:&error];

// do something with fetchedTracks

...これをサブクラスにどのようにプラグインするかは別の問題です-バッチフォールトリクエストを実行する前にフェッチされた結果が必要なためNSArrayController、オーバーライド内でこのメソッドを使用する方法はすぐにはわかりません。fetchWithRequest:余談ですが、遅延フェッチ フラグを試してみましたか?

于 2013-01-21T18:04:37.033 に答える