我有2个观点。使用NSFetchResultsController从Core Data中显示购物列表。第二个使用简单的NSFetchRequests显示此列表中的项目。两个视图都包含UITableView。
当我启动应用程序时,我创建了NSFetchResultsController(由ActiveFetchResults子类化)
-(id)initActiveFetch{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Lista" inManagedObjectContext:[CoreDataHandler context]];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"archive == 0 AND deleted == NO"];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
if (self=[[ActiveFetchResults alloc]
initWithFetchRequest:request
managedObjectContext:[CoreDataHandler context]
sectionNameKeyPath:nil
cacheName:nil])
{
self.delegate = self;
}
[request release];
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self sections] count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSInteger)numberOfRowsInSection{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:0];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ActiveListsCell* cell;
cell = (ActiveListsCell*)[tableView dequeueReusableCellWithIdentifier:@"ActiveLists"];
if (cell == nil) {
cell = [[[ActiveListsCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"ActiveLists"] autorelease];
}
NSManagedObject *managedObject = [self objectAtIndexPath:indexPath];
[cell setLista: (Lista*)managedObject];
NSLog(@"%@, %@, %d ",managedObject, [managedObject name], [[managedObject items] count]);
cell.activeListsDelegate = self;
[cell.roundedView setAlpha:1.0];
cell.button.alpha = 1.0;
cell.counter.alpha = 1.0;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:section];
return [sectionInfo name];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [self sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [self sectionForSectionIndexTitle:title atIndex:index];
}
- (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];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
//-(BOOL)performFetch:(NSError **)error{
// ActiveFetchResults* ss = self;
// self = [self initActiveFetch];
//
// self.listView = ss.listView;
// self.listView.activeFetch = self;
// [self.listView.tableView setDelegate:self];
// [self.listView.tableView setDataSource:self];
//
// [ss release];
// return [super performFetch:error];
//}
- (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:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
if ([anObject isKindOfClass:[Lista class]]) {
Lista* lista = (Lista*)anObject;
if ([[lista deleted] boolValue]) {
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationLeft];
}
}
else
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
ActiveListsCell* activeCell = (ActiveListsCell*)cell;
NSManagedObject *managedObject = [self objectAtIndexPath:indexPath];
[activeCell setLista: (Lista*)managedObject];
}
当我转到第二个视图并通过将项目对象添加到核心数据时为所选列表添加新项目并返回列表视图时,它仍然显示旧数量的对象。列表的items属性应显示此列表的所有Items对象是一个NSarray对象,其项目计数不包括新添加的对象。但第二个视图向我显示了所有添加了这些新项目的项目。
简而言之,通过使用NSFetchResultsController看起来我尽管使用了“performFetch:”函数,但我从第一次获取中冻结了所有对象并且没有响应更改。在第二个视图中使用简单的NSFetchRequest时,一切正常。
有人能告诉我为什么NSFetchResultsController对象保持冻结状态并且在核心数据记录发生变化时不会改变吗?
答案 0 :(得分:1)
可能的问题:
您在更新或添加对象后是否保存了NSManagedObjectContext
?
尝试添加此案例
case NSFetchedResultsChangeUpdate:
[self.tableView reloadData];
break;
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
方法中的
每次执行fetch后尝试重新加载tableview的数据:
[self.tableView reloadData];
如果仍然无效,请查看Apple的核心数据配方示例代码:http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html