前回のコードに問題があることがわかった。
バグ
画面からはみ出る程度に件数を増やすと次のケースでクラッシュすることがわかった。
(1) 初期表示
(2) 検索実行
(3) キャンセルで元の一覧戻り、下へスクロール
⇒ クラッシュ原因
検索時の NSFetchedResultController が、検索後に元の画面へ戻った時に使用されていた。どういうことかというと、元々10件のデータがあったにもかかわらず、検索で絞り込まれて1件となった後、元の画面に戻ってもその1件のままとなっていた。その状態で下へスクロールして見えていなかったデータを表示しようとした時に -tableView:cellForRowAtIndexPath: が呼び出され、そこで NSFetchedResultController に存在しない Indexを指定してエラーとなっていた(例:結果が1件にもかかわらずスクロールによって現れた 10件目のデータへアクセスしようとしていた)。
元の画面に戻った時に NSFetchedResultController の検索条件を元に(全件)戻し、フェッチをやり直す必要がある。
修正
検索完了時に NSFetchedResultController の検索条件を元に戻し、再フェッチする。UISearchBarの「キャンセル」ボタンが押された時を検索完了とすると UISearchBarDelegate のメソッドにこれらの処理を記述できる。
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { [self.fetchedResultsController.fetchRequest setPredicate:nil]; [self reloadFetchedResultsController]; }条件をクリア(nil)した上で再フェッチを行う。
-(void)reloadFetchedResultsController { NSError *error = nil; [NSFetchedResultsController deleteCacheWithName:@"UserSearch"]; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } }
ソースコード
SearchSample at 2010-07-20 from xcatsan's iOS-Sample-Code - GitHub
Responses
Leave a Response