1

それぞれに 1 つのカテゴリを持つアイテムがあります。を使用しNSFetchedResultsControllerてアイテムを表示し、カテゴリ名ごとにセクションにグループ化します。

self.fetchedResultsController = [Item MR_fetchAllSortedBy:@"category.categoryName" ascending:YES withPredicate:nil groupBy:@"category.categoryName" delegate:self];

しかし、以下のように 2 つの新しい項目を追加すると、カテゴリを持つ項目のみがリストに挿入されます。アプリを再起動すると、カテゴリ名のないものがセクションなしで上部に表示されます。

これは私が挿入を行う方法です(Magical Recordを使用):

Category *category = [Category MR_createEntity];
category.categoryName = @"My Category";

Item *itemWithCategory = [Item MR_createEntity];
itemWithCategory.itemName = @"Item with category";
itemWithCategory.category = category;

Item *itemWithoutCategory = [Item MR_createEntity];
itemWithoutCategory.itemName = @"Item without category";

[[NSManagedObjectContext MR_contextForCurrentThread] MR_saveToPersistentStoreAndWait];

が子オブジェクトの属性を参照していて、この子オブジェクトが nil のNSFetchedResultsController場合、新しい項目が追加されたときに に通知されないのはなぜですか?sectionNameKeyPath

4

1 に答える 1

0

fetchedResultsController の結果を nil セクション値でセクション化しようとして、非常に不運に見舞われました。ドキュメントには言及されていませんが、実際には許可されていないと思います。

ドキュメントからも明らかではありませんが、セクション化に使用するプロパティは、実際にはモデル化されたプロパティである必要はなく、合成することができます。(これは、たとえば日付をセクションとして使用する場合に非常に便利です。)

したがって、私の通常の回避策は、合成の読み取り専用プロパティを作成することです。たとえば、 nil でない場合はItem.formattedCategoryTitleそれを返し、そうでない場合は適切なプレースホルダーを返します。おそらく少し遅くなります-セクションプロパティがデータベースにあるItem.category.categoryName場合、コアデータが利用されると思います-しかし、それは機能します。


(PS 別の小さな落とし穴: ドキュメントでは、「結果セットまたはセクション情報に影響を与えるコンテキストの変更は処理され、それに応じて結果が更新される」と主張しています。これは厳密には正しくありません: フェッチされたエンティティへの変更のみが通知されます。

この場合、Categoryオブジェクト自体が変更されても (新しいタイトルが割り当てられるなど)、fetchedResultsController は通知しません。この場合、Itemオブジェクトへの変更のみを認識します。コントローラーがオブジェクトの存在、順序、セクションなどを再評価するには、オブジェクト自体を変更する必要があります。

これが発生する可能性がある場合は、次のいずれかを実行できます: カテゴリの変更を監視するためだけに 2 つ目の fetchedResultsController をセットアップし、メイン コントローラーの再フェッチをトリガーします。または、 NSManagedObjectContextObjectsDidChangeNotificationそこでカテゴリの変更を登録して検出します。またはCategory、たとえば、それらに null の変更を加えることによって、変更された場合にその項目を「ダーティ」にするように記述します。私はこれらの方法を試しましたが、より良い方法を聞くことができます!)

于 2013-05-26T18:59:48.813 に答える