47

NSFetchedResultsController を使用して、日付を使用してセクション化された一連のオブジェクトを表示します。新規インストールでは、すべてが完全に機能し、オブジェクトがテーブル ビューに表示されます。ただし、アプリを再起動するとクラッシュするようです。NSFetchedResultsController を初期化するときにキャッシュを指定し、そうしないと完全に機能します。

NSFetchedResultsController を作成する方法は次のとおりです。

- (NSFetchedResultsController *)results {
    // If we are not nil, stop here
    if (results != nil)
        return results;

    // Create the fetch request, entity and sort descriptors
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"utc_start" ascending:YES];
    NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];

    // Set properties on the fetch
    [fetch setEntity:entity];
    [fetch setSortDescriptors:descriptors];

    // Create a fresh fetched results controller
    NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"day" cacheName:@"Events"];
    fetched.delegate = self;
    self.results = fetched;

    // Release objects and return our controller
    [fetched release];
    [fetch release];
    [descriptor release];
    [descriptors release];
    return results;
}

アプリがクラッシュしたときに表示されるメッセージは次のとおりです。

FATAL ERROR: The persistent cache of section information does not match the current configuration.  You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'FATAL ERROR: The persistent cache of section information does not match the current configuration.  You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:'

私はこれを引き起こすような特別なことをしているとは思わないので、なぜそれがそう言っているのかについては本当に手がかりがありません. 唯一の潜在的な問題は、新しいオブジェクトを作成するときに次のように作成するセクション ヘッダー (日) です。

// Set the new format
[formatter setDateFormat:@"dd MMMM"];

// Set the day of the event
[event setValue:[formatter stringFromDate:[event valueForKey:@"utc_start"]] forKey:@"day"];

前述したように、キャッシュが含まれていなければ、これはすべて正常に機能します。どんな助けでも大歓迎です!

4

12 に答える 12

65

Apple が新しい iOS 4.0 をリリースしたとき、私のアプリの 1 つで同様の問題が発生しました。探す:

fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];

パラメータ cacheName の値を nil に設定します。それは私にとってはうまくいきました。お知らせ下さい。

于 2010-07-29T13:49:05.843 に答える
30

MacBook Pro で Snow Leopard 10.6.4 と最新の SDK にアップグレードしたときに、同じエラーが発生し始めました。

結局のところ、私たちの多くはルールに準拠していないコードを使用していましたが、CoreData が実際には独自のルールに従って動作していなかったため、それを知りませんでした。

具体的には、物事をフェッチするとキャッシュされ、4.0 では、以前の SDK でキャッシュが削除された場合でも、そのキャッシュは自動的に削除されません。

私にとって、解決策は簡単でした。キャッシュを消去するクラス メソッドを使用しました。個々のエンティティを指定できますが、ここでは nil を指定しているため、この特定のスタートアップ コードですべてを実行します。

[NSFetchedResultsController deleteCacheWithName:nil];

突然、CoreData に慣れるためだけに取り組んだ小さなアプリが再び機能するようになりました。

于 2010-08-01T20:44:44.620 に答える
15

のドキュメントから直接NSFetchedResultsController

取得リクエストの変更

取得リクエストを単純に変更して結果を変更することはできません。取得リクエストを変更する場合は、次のことを行う必要があります。

  1. キャッシュを使用している場合は、キャッシュを削除します ( を使用deleteCacheWithName:)。通常、フェッチ リクエストを変更する場合は、キャッシュを使用しないでください。

  2. 取得リクエストを変更します。

  3. 呼び出しperformFetch:ます。

于 2012-01-01T03:26:03.750 に答える
6

同様の問題が発生しました。Debugger Console を調べたところ、キャッシュされたオブジェクトとフェッチされたオブジェクトが何であるかが示され、それらが矛盾している理由を突き止めることができました。私の場合、それは別の述語が原因でした。

述語の値は動的ではないため、述語ごとに異なるキャッシュ名を指定できます。これにより、指定した「タイプ」ごとにキャッシュが作成されます。

キャッシュの必要性を評価する必要があると思います。nil を指定すると、すべての呼び出しでフェッチが行われます。

エラーは、フェッチ リクエストに何らかの変更がある場合にのみ発生することがわかりました。新しい NSFetchRequest を作成する場合、述語を変更する場合、またはソート記述子を変更する場合は、キャッシュを削除するか、別のキャッシュを使用する必要があります。それ以外の場合は、同じ NSFetchRequest があることを確認するか、NSFetchedResultsController が保持されていることを確認してください。これで問題が解決するはずです。

于 2011-03-10T18:55:40.050 に答える
3

シミュレーターを使用している場合は、リセットしてみてください。エンティティ マップを変更したため、残りのキャッシュによって混乱していると思います。そうでない場合は、エラーの内容を試すことができます。

- (void)applicationWillTerminate:(UIApplication *)application {
    [NSFetchedResultsController deleteCacheNamed:@"Events"];
    //etc
}
于 2010-04-25T20:26:04.447 に答える
3

Xcode 7 (ベータ 4) でも例外が発生します。

キャッシュを無効にするか、+deleteCacheWithName を使用せずに、NSFetchedResultsController のフェッチ要求、その述語、またはそのソート記述子を不正に変更しました:

注:これは、Xcode 7 で作成され、最新 (iOS 9) の展開ターゲットを使用して、標準の Xcode CoreDataの「ボイラープレート」コードを含む、変更されていない Xcode の「テンプレート」マスター/ディテール iOS アプリを使用しています。

シミュレーターでアプリを再起動したときに最初に気付きました。Xcode経由でアプリを数回起動および停止していたところ、それが起こりました。そしてそれは起こり続けました。私はいくつかの実験を行うことにしました。結果は次のとおりです。

  • シミュレーターでアプリを停止するたびに、その後の起動時に例外が発生しました。
  • シミュレーターのホームボタンを使用してアプリを停止するたびに、正常に再起動できました。

この問題は、次の方法のいずれかを使用して、次のように修正できます。

  • AppDelegate のapplication didFinishLaunchingWithOptionsメソッドで、次の SwiftNSFetchedResultsController.deleteCacheWithName(nil)または Objective-C[NSFetchedResultsController deleteCacheWithName:nil];コードを追加します。これにより、破損したキャッシュがクリアされます。
  • シミュレーターで、[シミュレーター] メニューから [コンテンツと設定のリセット] を選択します。これで問題は解決しますが、テスト データが失われます

また、これは Xcode を介して実行し、クリーンアップする前にアプリを停止した結果だと思います。これは実機では見たことがありません。

于 2015-08-07T02:44:25.237 に答える
1

同じ - (NSFetchedResultsController *)results メソッドを実装するクラスはいくつありますか?それぞれに異なるキャッシュを使用しますか? 私は同じ問題を抱えていましたが、NSPredicate が異なるため、一部のクラスに別のキャッシュ名を使用して修正したと思います。

于 2010-06-25T21:47:20.463 に答える
1

ホームボタンを使用してシミュレーターを終了していますか?それとも Xcode でアプリを終了していますか? アプリがキャッシュへの書き込みを完了する時間がない可能性があります。ホームボタンでアプリを終了してみてください。

于 2010-04-25T23:06:12.440 に答える
1

私は同じ問題を抱えていました。
修正するために[NSFetchedResultsController deleteCacheWithName:@"cacheName"];、resultsController の init の前に を置きました。彼は初めてそこに行くだけなので、私のために働きます。

于 2012-01-07T16:35:43.637 に答える