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"];
先に述べたように、キャッシュが含まれていない場合、これはすべて正常に機能します。助けてくれてありがとう!
Appleが新しいiOS 4.0をリリースしたとき、私のアプリの1つに同様の問題がありました。検索:
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
そして、パラメーターcacheNameの値をnilに設定します。それは私のために働いた、あなたのためにそれが願っています。お知らせ下さい。
MacBook ProでSnow Leopard 10.6.4と最新のSDKにアップグレードすると、同じエラーが発生し始めました。
結局のところ、私たちの多くはルールに準拠していないコードを使用していましたが、CoreDataが実際に独自のルールに従って動作していないため、それを知りませんでした。
具体的には、取得したものがキャッシュされます。4.0では、以前のSDKでキャッシュが削除された場合、そのキャッシュは自動的には削除されません。
私にとって、解決策はシンプルでした。キャッシュを削除するクラスメソッドを使用しました。個々のエンティティを指定できますが、nilを指定して、この特定の起動コードですべてを実行します。
[NSFetchedResultsController deleteCacheWithName:nil];
突然、CoreDataに慣れるためだけに取り組んだ小さなアプリが再び動作するようになりました。
NSFetchedResultsController
のドキュメントから直接:
フェッチ要求の変更
フェッチリクエストを変更して結果を変更することはできません。フェッチ要求を変更する場合は、次のことを行う必要があります。
キャッシュを使用している場合は、(
deleteCacheWithName:
)。通常、フェッチ要求を変更する場合は、キャッシュを使用しないでください。フェッチ要求を変更します。
呼び出し
performFetch:
。
同様の問題が発生しました。デバッガーコンソールを調べたところ、キャッシュされたオブジェクトとフェッチされたオブジェクトが何であるかが示され、それらが矛盾している理由を突き止めることができました。私の場合、それは別の述語が原因でした。
私の述語の値は動的ではないため、述語ごとに異なるキャッシュ名を指定できます。これにより、指定した「タイプ」ごとにキャッシュが作成されます。
キャッシュの必要性を評価する必要があると思います。 nilを指定することは、すべての呼び出しでフェッチが行われることを意味します。
このエラーは、フェッチ要求に変更があった場合にのみ発生することがわかりました。新しいNSFetchRequest OR述語を変更するORソート記述子を作成する場合は、キャッシュを削除するか、別のキャッシュを使用する必要があります。それ以外の場合は、同じNSFetchRequestを持っているか、NSFetchedResultsControllerが保持されていることを確認して、問題を解決してください。
シミュレーターを使用している場合は、リセットしてみてください。エンティティマップを変更したため、残りのキャッシュが混乱していると思います。そうでない場合は、エラーが言うことを試すことができます:
- (void)applicationWillTerminate:(UIApplication *)application {
[NSFetchedResultsController deleteCacheNamed:@"Events"];
//etc
}
Xcode 7(ベータ4)でも例外は発生します。
キャッシュを無効にしたり、+ deleteCacheWithNameを使用したりせずに、NSFetchedResultsControllerのフェッチリクエスト、その述語、またはそのソート記述子を不正に変更しました:
注:これは変更されていないXcode "テンプレート" Master-Detail iOSアプリと標準のXcode CoreData "ボイラープレート"Xcode 7で作成され、最新の(iOS 9)展開ターゲットを使用して作成されたコード。
シミュレータでアプリを再起動したときに、最初に気が付きました。 Xcodeを使用してアプリを数回起動および停止していたところ、それが起こりました。そしてそれは起こり続けました。私はいくつかの実験を行うことにしました、そして結果:
問題は次のように修正であり、以下の方法の一方または他方を使用できます。
application didFinishLaunchingWithOptions
_メソッドで、次のSwift NSFetchedResultsController.deleteCacheWithName(nil)
またはObjective-C _[NSFetchedResultsController deleteCacheWithName:nil];
_コードを追加します。これにより、破損したキャッシュがクリアされます。また、これはXcodeを介して実行し、クリーンアップする前にアプリを停止することのアーティファクトであると私は思います。実際のデバイスではこれを見たことがありません。
最近同じ問題が発生した場合、問題はなんとかしてCore Dataがキャッシュをクリーンアップしないため、最初は正常に動作しますが、その後は動作しないことです。次に、NSFetchRequestを初期化した直後にこの行を挿入します
[NSFetchedResultsController deleteCacheWithName:@"Name"];
ホームボタンを使用して、またはXcodeでアプリを終了して、シミュレータを終了しますか?たぶん、アプリがキャッシュへの書き込みを完了するための時間を取得していないのかもしれません。ホームボタンを使ってアプリを終了してみてください。
私も同じ問題を抱えていました。
修正するために、[NSFetchedResultsController deleteCacheWithName:@"cacheName"];
resultsControllerの初期化の前。彼は初めてそこに行くだけなので、私にとってはうまくいきます。
Ray Wenderlichで見つけた forums ということ
データストアに新しいものを追加したときにフェッチリクエストがまだ作成されていない場合にのみクラッシュすることに注意してください、つまりLocationsビューがまだロードされていない場合。ビューが既にロードされている場合は、正常に機能します。おかしい、えっ?
だから、私の場合に起こったことはこれです:
解決策は、オブジェクトを作成する前にフェッチが完了していることを確認することです(フェッチに影響します)。
あるいは、キャッシュを削除することもできますが、実際にはパフォーマンスが低下します。
デバッガからの警告に注意してください
キャッシュを無効にしたり、+ deleteCacheWithNameを使用したりせずに、NSFetchedResultsControllerのフェッチリクエスト、その述語、またはそのソート記述子を不正に変更しました:
変更されたのはリクエスト、述語、またはソート記述子ではなく、フェッチが行われている間に結果セットを変異させたとより正確に説明できるため、この状況をまったくキャプチャしません進捗。
この小さな雑学を追跡するのに私は永遠にかかりました。あなたが恩恵を受けることを願っています。
同じように実装するクラスの数-(NSFetchedResultsController *)resultsメソッド、それぞれに異なるキャッシュを使用しますか?私は同じ問題を抱えていましたが、異なるNSPredicateを持っているため、いくつかのクラスの前に別のキャッシュ名を使用することでそれを修正すると思います。