核心数据主从应用程序。
当我tableView
加载它时,它会显示一个视图UIButtons
以选择您要查看的项目类别。for 按钮采用该类别并基于该IBAction
类别创建NSFetchedResultsController
带有 a的 a。NSPredicate
按钮之间的唯一区别是,8 个按钮中的 2 个设置为根据设置为对象属性的/值predicate
来抓取所有对象。其他 6 个按钮根据它们的“类别”抓取所有对象,这又是对象上设置的属性BOOL
NSNumber
NSString
我的问题:
当我选择按类别 ( ) 抓取对象的任何按钮时,NSString
一切正常。它使用所有正确的对象加载 tableview 我选择了一行委托方法-controller didChangeObject
被调用的类型是NSFetchedResultsChangeUpdate
我将对象传递给的类型DetailViewController
,一切都很好。
当我选择任何按BOOL
值抓取对象的按钮时,一切似乎都可以正常工作。表格视图加载所有正确的对象并正确显示。但是,当我选择一行时,-controller didChangeObject
会使用类型调用委托方法,NSFetchedResultsChangeDelete
并且我的对象会从 tableview 中删除。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];
}