web-dev-qa-db-ja.com

(NSFetchedResultsController):ストア情報のタイムスタンプを更新するためにキャッシュファイルを読み取れませんでした

プロジェクトをXcode 8にアップグレードしました。今、Xcode 8とiOS 10の組み合わせでこのエラーログを取得しています。

以下のコードでcacheNameをnilに設定すると修正されるようです。

NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:NULL cacheName:@"myCache"];

このエラーログを取り除き、FRCでキャッシュを使用するにはどうすればよいですか?

35
iCanCode

このエラーはアプリのクラッシュを引き起こす可能性があるため、無視しないでください。これは、ファイル記述子リークのiOS 10バグに関連しています。 openradarおよびApple Bug Reporter。

何が起こるか:NSFetchedResultsControllerにnon-nil cacheNameを使用してView Controllerをロードすると、管理オブジェクトコンテキストを保存するたびに、fetchedResultsControllerのsectionInfoキャッシュファイルを指す1つ以上のファイル記述子が開きます。つまり、コンテキストを255回保存すると、デバイスで開くことができるファイルの最大数に達し、新しいリソースを開くことができなくなり、その後のxibファイル、イメージ、データベースなどのオープンが失敗します。

この問題は、iOS 10にアップグレードされたデバイスで既に生産されている(xcode 7で構築された)アプリでも発生します。

一時的な解決策は、nilをcacheNameとして使用してNSFetchedResultsControllerキャッシングを無効にすることです。

NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:NULL cacheName:nil];

明らかにこの方法では、キャッシュの利点を得ることができません。 Appleがバグをできるだけ早く修正することを望みます。10.2ベータ1に対してテストするつもりです。

OPEN RADAR 2836155

[〜#〜] edit [〜#〜]iOS 10.2ベータ1では、バグは発生しません。(今のところ)解決されています。

26
Donnit

初めてここで答えを提供しますが、ここに行きます...

このエラーが発生し、特定のケースの解決策を見つけました。

NSFetchedResultsControllerを使用していました。次に、状態の復元を追加しました。このエラーは、復元時に表示されるようになりました。 Navigation Barを使用して前のView Controllerに戻ると、データがすべて欠落/不正でした。

NSFetchedResultsControllerドキュメントを読むと、次のことがわかりました。

重要

デリゲートは、変更追跡を有効にするために、少なくとも1つの変更追跡デリゲートメソッドを実装する必要があります。 controllerDidChangeContent(_:)の空の実装を提供するだけで十分です。

空のcontrollerDidChangeContent(_:)を指示どおりに実装しました。これで、すべてが正常に機能し、質問からのエラーメッセージが消えました。明確にするために、フェッチされた結果コントローラーとともに各View Controllerに次のコードを追加しました。

// NSFetchedResultsController change tracking methods
    func controllerDidChangeContent(_ controller: 
NSFetchedResultsController<NSFetchRequestResult>) {
        // empty: see documentation
    }

お役に立てれば。

2
curieux

上記のエラーメッセージにさらに注意を払った後、アプリが大量のファイル記述子を作成し、キャッシュフォルダー内のファイルを開き、決して閉じたり解放したりしないことがわかりました。そのため、今のところNSFetchedResultsControllerキャッシングを無効にする方が良いでしょう。

希望Appleは問題を解決します

0
Saranjith