我可以在我的应用程序中创建新的托管对象,在单独的视图中,我有一个表视图显示了我所有的对象.
当我创建一个新的托管对象(在一个完全独立的视图中)时,我发送一个通知,它试图让我的表视图重新加载包含刚创建的新对象的新数据.
我没有编辑表视图.
只有一个管理上下文.
我无法掌握我做错了什么如果我关闭应用程序并重新启动,我的新对象在表视图中.我正在尝试调用reloadData,当我收到一个新的对象的通知,并且我也尝试再次执行提取,但我最终得到的是一个空的表视图.
在代码方面,我的ListViewController:
@interface MyNotesViewController : UIViewController { NSManagedObjectContext * __managedObjectContext; UITableView * _notesTableView; MyNotesTableViewDelegate_DataSource * _tableDelegate_DataSource; }
我的viewDidLoad看起来像这样:
- (void)viewDidLoad { [super viewDidLoad]; _tableDelegate_DataSource = [[MyNotesTableViewDelegate_DataSource alloc] init]; _tableDelegate_DataSource.managedObjectContext = __managedObjectContext; [_notesTableView setDataSource:_tableDelegate_DataSource]; NSError * _coreDataError; BOOL success = [[_tableDelegate_DataSource fetchedResultsController] performFetch:&_coreDataError]; if(success){ [_notesTableView reloadData]; } }
在我的委托/ datasource对象中,我有:
@interface MyCommutesTableViewDelegate_DataSource : NSObject <UITableViewDataSource,NSFetchedResultsControllerDelegate> { NSManagedObjectContext * __managedObjectContext; NSFetchedResultsController * __fetchedResultsController; } @property (nonatomic,retain) NSManagedObjectContext *managedObjectContext; @end
实施摘录:
-(NSFetchedResultsController*)fetchedResultsController{ if(!__fetchedResultsController){ NSFetchRequest * request = [[NSFetchRequest alloc] init]; [request setEntity:[NSEntityDescription entityForName:@"Note" inManagedObjectContext:__managedObjectContext]]; [request setFetchBatchSize:10]; NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; __fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:__managedObjectContext sectionNameKeyPath:nil cacheName:nil]; __fetchedResultsController.delegate = self; [request release]; } return __fetchedResultsController; }
我在这里有UITableView数据源的方法:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ id <NSFetchedResultsSectionInfo> sectionInfo = [[__fetchedResultsController sections] objectAtIndex:section]; return [sectionInfo numberOfObjects]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"NotesTableViewCell"; NotesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { NSArray * topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NotesTableViewCell" owner:nil options:nil]; for(id currentObject in topLevelObjects){ if([currentObject isKindOfClass:[UITableViewCell class]]){ cell = (NotesTableViewCell*) currentObject; break; } } } // Configure the cell. Note * _note = [__fetchedResultsController objectAtIndexPath:indexPath]; [...] return cell; }
UPDATE
我恢复了简单地请求所有对象,因为我不得不快速解决我的问题,然后我意识到,在保存我的上下文之后,我以前在应用程序启动中使用的提取请求现在没有返回任何数据,没有错误,但它只是没有回报.
所以我想没有问题,我如何实现NSFetchResultsController.但是,在保存新对象后,请求如何开始不返回结果?
注意,如果我重新启动,我仍然会收到我的所有对象,包括新添加的对象.
标准要求:
-(NSArray*)getNotes{ NSFetchRequest * request = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:[self managedObjectContext]]; [request setEntity:entity]; NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; NSError * coreDataError; NSArray * fetchedObjects = [[self managedObjectContext] executeFetchRequest:request error:&coreDataError]; [request release]; if(fetchedObjects != nil){ return fetchedObjects; } else { NSLog(@"ERR: %@",coreDataError); return nil; } }
我正在等待一个通知,告诉我一个新的对象已被添加到Core Data,然后我调用上面的方法,然后在我的tableview上调用reloadData …
解决方法
您正在将UITableViewController设置为NSFetchedResultsControllerDelegate.那很好.现在尝试在TableViewController中实现controllerDidChangeContent:方法,如下所示:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView reloadData]; }
您的NSFetchedResultsController将侦听Core Data中的已删除或新对象,并通知其委托(您的TableViewController)更改.检查Xcode中的Core Data模板项目,使用UITableView中的添加和删除动画更好地实现这一点.