I'm a weekend warrior when it comes to programming, so I have probably done something wrong...
在编程方面,我是个周末战士,所以我可能做错了什么……
I have a split view controller, core data, nsfetchedResultsController, all that works great. I now have an option for the user to create a backup file of the persistentStore.sqlite file. When the user restores from a backup file, the tableview doesn't reflect any change. And on top of that, can't make any lasting changes from then on from the tableview add/delete. When I quit the app and restart it, all the data is there from the back up and all is working well.
我有一个分屏视图控制器,core data, nsfetchedResultsController,所有这些都很有用。我现在有一个选项供用户创建persistentStore的备份文件。sqlite文件。当用户从备份文件中恢复时,表视图不会反映任何更改。最重要的是,从那时起,不能对tableview添加/删除进行任何持久的更改。当我退出应用程序并重新启动它时,所有的数据都在后台,一切都运行良好。
How can I force the tableview to get the now new info from the fetched results controller? Or how do I force the
如何强制tableview从fetchedresultscontroller获取新信息?或者我如何强迫
Here's some scatterings of what I have tried so far without success:
下面是一些我尝试过但没有成功的例子:
MasterViewController.m
- (void)viewDidLoad
{
context = [[OSCDStackManager sharedManager] managedObjectContext];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadFetchedResults) name:OSFilesUpdatedNotification object:nil];
- (void)reloadFetchedResults:(NSNotification*)note {
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
if (note) {
[self.tableView reloadData];
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
[self.tableView endUpdates];
[self.tableView reloadData];
}
from a manual refresh pulldown on the tableview...
从手动刷新到tableview…
-(void) updateTable{
context = [[OSCDStackManager sharedManager] managedObjectContext];
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
//[self.tableView endUpdates];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
- (NSFetchedResultsController *)fetchedResultsController
{
context = [[OSCDStackManager sharedManager] managedObjectContext];
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
//[NSFetchedResultsController deleteCacheWithName:@"cache"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
Even though this is an app for my neighbor, I'd hate tell him to kill and restart the app after a back up...
即使这是我邻居的一个应用,我也不愿意让他在备份后关闭并重新启动这个应用……
Solution ended up being a combination of both answers below,
解决方案是下面两个答案的组合,
- (void)reloadFetchedResults{
self.fetchedResultsController = nil;
[NSFetchedResultsController deleteCacheWithName:@"cache"];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.tableView reloadData];
}
3 个解决方案
#1
2
nil out your FRC
零你FRC
-(void)reloadData
{
NSError *error = nil;
self.fetchedResultsController = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
else
[self.tableView reloadData];
}
** EDIT ** in case it's not obvious with the 'self' at the front you'll need somewhere in your class
** *编辑**,以防前面的“自我”不明显,你需要在课堂上的某个地方
-(NSFetchedResultsController *)fetchedResultsController
{
if (!_fetchedResultsController)
{
_fetchedResultsController = [NSFetchedResultsController alloc]initWithFetchRequest:aFetchRequest
managedObjectContext:aManagedObjectContext // the main thread MOC
sectionNameKeyPath:nil cacheName:nil];
// addional FRC setup etc.
}
return _fetchedResultsController;
}
#2
4
Did you delete the cache?
你删除缓存了吗?
You need to first set the cache name to the fetchedResultsController
(notice the cacheName
argument at the end):
您需要首先将缓存名设置为fetchedResultsController(请注意末尾的cacheName参数):
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:query
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:@"CACHE_NAME"];
Then delete the cache when you make an update:
然后在进行更新时删除缓存:
[NSFetchedResultsController deleteCacheWithName:@"CACHE_NAME"];
After doing this, load from core data again by doing this:
这样做之后,再次从core data加载:
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error loading data %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self.tableView reloadData];
#3
0
If you are replacing the sqlite file you are probably best tearing everything down and starting with a fresh managed object context. This is a similar question to deleting the store.
如果要替换sqlite文件,那么最好将所有内容都分解,并从一个新的托管对象上下文开始。这与删除存储类似。
#1
2
nil out your FRC
零你FRC
-(void)reloadData
{
NSError *error = nil;
self.fetchedResultsController = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
else
[self.tableView reloadData];
}
** EDIT ** in case it's not obvious with the 'self' at the front you'll need somewhere in your class
** *编辑**,以防前面的“自我”不明显,你需要在课堂上的某个地方
-(NSFetchedResultsController *)fetchedResultsController
{
if (!_fetchedResultsController)
{
_fetchedResultsController = [NSFetchedResultsController alloc]initWithFetchRequest:aFetchRequest
managedObjectContext:aManagedObjectContext // the main thread MOC
sectionNameKeyPath:nil cacheName:nil];
// addional FRC setup etc.
}
return _fetchedResultsController;
}
#2
4
Did you delete the cache?
你删除缓存了吗?
You need to first set the cache name to the fetchedResultsController
(notice the cacheName
argument at the end):
您需要首先将缓存名设置为fetchedResultsController(请注意末尾的cacheName参数):
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:query
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:@"CACHE_NAME"];
Then delete the cache when you make an update:
然后在进行更新时删除缓存:
[NSFetchedResultsController deleteCacheWithName:@"CACHE_NAME"];
After doing this, load from core data again by doing this:
这样做之后,再次从core data加载:
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error loading data %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self.tableView reloadData];
#3
0
If you are replacing the sqlite file you are probably best tearing everything down and starting with a fresh managed object context. This is a similar question to deleting the store.
如果要替换sqlite文件,那么最好将所有内容都分解,并从一个新的托管对象上下文开始。这与删除存储类似。