コア データ マスター/ディテール アプリケーション。
tableView
ロードすると、表示するアイテムのカテゴリを選択するためのビューが表示UIButtons
されます。IBAction
ボタンの はそのカテゴリを取得し、そのカテゴリに基づいて を作成しますNSFetchedResultsController
。NSPredicate
ボタン間の唯一の違いは、8 つのボタンのうち 2 つが、オブジェクトのプロパティとして設定された/値にpredicate
基づいてすべてのオブジェクトを取得するように設定することです。他の 6 つのボタンは、オブジェクトに設定されたプロパティである「カテゴリ」に基づいてすべてのオブジェクトを取得します。BOOL
NSNumber
NSString
私の問題:
カテゴリ ( NSString
) でオブジェクトを取得するボタンのいずれかを選択すると、すべて正常に動作します。テーブルビューにすべての正しいオブジェクトをロードします。行を選択すると、オブジェクトに渡し-controller didChangeObject
たタイプでデリゲート メソッドが呼び出され、すべて問題ありません。NSFetchedResultsChangeUpdate
DetailViewController
値でオブジェクトを取得するボタンのいずれかを選択すると、BOOL
すべてが正常に機能しているように見えます。テーブルビューはすべての正しいオブジェクトをロードし、適切に表示します。ただし、行を選択すると、その型でデリゲート メソッド-controller didChangeObject
が呼び出されNSFetchedResultsChangeDelete
、オブジェクトがテーブルビューから削除されます。DetailViewController
がスタックにプッシュされ、すべての情報が正しく表示されます。
フェッチされた結果からオブジェクトが削除される理由がわかりません。意味がありません。BOOL
プロパティではなくプロパティによるフェッチ以外に、私がやっていることに違いはないからですNSString
。
また; 行を選択すると、 内のオブジェクトのプロパティ値が変更されます-tableview didSelectRowAtIndexPath
。変更するプロパティは、アイテムが表示されたかどうかを追跡するための単なる BOOL 値です。このプロパティ値を変更するこのコード行を削除すると、すべて正常に動作します。BOOL
このコード行が他のカテゴリに影響せず、プロパティから取得するカテゴリにのみ影響する理由がわかりません。
コード: カテゴリ ボタンの IBAction
-(IBAction)goToPage:(id)sender {
BOOL wishList = NO;
BOOL cellar = NO;
if ((UIButton*)sender == americanButton) {
selectedCategory = @"american";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == canadianButton) {
selectedCategory = @"canadian";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == irishButton) {
selectedCategory = @"irish";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == japaneseButton) {
selectedCategory = @"japanese";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == scottishButton) {
selectedCategory = @"scotch";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == verticalsButton) {
selectedCategory = @"verticals";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == otherButton) {
selectedCategory = @"other";
selectedSubCategory = nil;
wishList = NO;
cellar = NO;
} else if ((UIButton*)sender == wishListButton) {
selectedSubCategory = @"wishlist";
selectedCategory = nil;
wishList = YES;
cellar = NO;
} else if ((UIButton*)sender == cellarButton) {
selectedSubCategory = @"cellar";
selectedCategory = nil;
wishList = NO;
cellar = YES;
}
if (wishList == YES) {
[self fetchMyWhiskiesFromCategory:@"1" andResetFetchResultsController:YES withAttribute:@"wishlist"];
} else if (cellar == YES) {
[self fetchMyWhiskiesFromCategory:@"1" andResetFetchResultsController:YES withAttribute:@"mycellar"];
} else {
[self fetchMyWhiskiesFromCategory:selectedCategory andResetFetchResultsController:YES withAttribute:@"category"];
}
}
- (void)fetchMyWhiskiesFromCategory:(NSString *)category andResetFetchResultsController:(BOOL)reset withAttribute:(NSString *)attribute
{
NSError *error = nil;
NSFetchedResultsController *resultsController = [self fetchedResultsControllerWithCategory:category andResetFetchResultsController:reset withAttribute:attribute];
if (![resultsController performFetch:&error]) {
NSLog(@"Error! %@", error);
}
}
- (NSFetchedResultsController *)fetchedResultsControllerWithCategory:(NSString *)category andResetFetchResultsController:(BOOL)reset withAttribute:(NSString *)attribute
{
if (reset == YES) {
// If asking for new results controller with new category
NSLog(@"Reset results");
self.fetchedResultsController = nil;
_fetchedResultsController = nil;
}
if (_fetchedResultsController != nil) {
//NSLog(@"returned Old Controller");
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
//Entity
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Whisky" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@",attribute, category];
[fetchRequest setPredicate:predicate];
//Sort all entities by name property (whisky name)
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//Create FetchedResultsController organizing by sections of first letter of name
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"name.stringGroupByFirstInitial" cacheName:nil];
//name.stringGroupByFirstInitial
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
行を選択しました
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController) {
self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
}
Whisky *whisky = [self.fetchedResultsController objectAtIndexPath:indexPath];
[whisky setIsNew:[NSNumber numberWithBool:NO]];
self.detailViewController.managedObjectContext = self.managedObjectContext;
self.detailViewController.whisky = whisky;
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
NSFetchedResultsController デリゲート
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeSection - ChangeInsert");
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeSection - ChangeDelete");
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeInsert");
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeDelete");
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
NSLog(@"didChangeObject - ChangeUpdate");
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeMove");
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}