我有一个实体Country
,其中包含一个属性downloaded
,其默认值为0,并且不由RestKit映射。我希望能够根据下载的属性将tableView分组为多个部分。一切都按预期工作,直到我尝试以编程方式自行更改下载的值。代码如下:
我正在尝试设置值 - 我的上下文是通过AppDelegate传递给控制器的mainQueueManagedObjectContext
。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Country *country = [self.fetchedResultsController objectAtIndexPath:indexPath];
[FGDataCalls downloadFieldGuide:country.countryId];
//Set up to get the thing you want to update
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Country" inManagedObjectContext:self.managedObjectContext]];
[request setPredicate:[NSPredicate predicateWithFormat:@"countryId = %@", country.countryId]];
NSError *error = nil;
country = [[self.managedObjectContext executeFetchRequest:request error:&error] lastObject];
if (error) {
NSLog(@"Error getting the country from core data: %@", error);
}
country.downloaded = 1;
error = nil;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Saving changes to country failed: %@", error);
}
}
FetchedResultsController:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Country" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Sort using the name property.
NSSortDescriptor *sortDownloaded = [[NSSortDescriptor alloc] initWithKey:@"downloaded" ascending:NO];
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:@[sortDownloaded, sortName]];
// Use the sectionIdentifier property to group into sections.
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"downloaded" cacheName:nil];
_fetchedResultsController.delegate = self;
self.fetchedResultsController = _fetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
初始化Restkit:
//Enable RestKit logging
//RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelInfo);
//RKLogConfigureByName("RestKit/CoreData", RKLogLevelTrace);
//RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
// Initialize RestKit
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:BaseURLString]];
// Initialize managed object store
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"FGDataModel" ofType:@"momd"]];
NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
BOOL success = RKEnsureDirectoryExistsAtPath(RKApplicationDataDirectory(), &error);
if (!success) {
RKLogError(@"Failed to create Application Data Directory at path '%@': %@", RKApplicationDataDirectory(), error);
}
objectManager.managedObjectStore = managedObjectStore;
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"FGDataModel.sqlite"];
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error];
if (! persistentStore) {
RKLogError(@"Failed adding persistent store at path '%@': %@", path, error);
}
// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
[managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Setup our object mappings
[FGDataCalls setupObjectMappings:managedObjectStore withObjectManager:objectManager];
// Save the MOC
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
appDelegate.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
我已尝试在此时以多种不同的方式保存上下文,包括块,我还没有让fetchedResultsController识别更新,甚至调用controllerWillChangeContent:
或controllerDidChangeContent:
。我已经使用MOC的deleteObject:
方法成功删除了一行,因此我的上下文处于正确的状态。我甚至可以在设置了下载的属性后从我的fetchedResultsController获取对象并查看它是否正确,但表永远不会更新。此外,在我更改属性后强制表重新加载不会产生任何结果。我知道这是一个具体的案例,但希望其他人遇到同样的问题,或者可以看到我出错的地方。
谢谢!
答案 0 :(得分:0)
保存时不应该
error = nil;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Saving changes to country failed: %@", error);
}
你应该做
error = nil;
if (![self.managedObjectContext saveToPersistentStore:&error]) {
NSLog(@"Saving changes to country failed: %@", error);
}
也就是说,假设FRC连接到相同的上下文,那么它应该在保存之前看到更改。您也不会显示您的FRC委托方法,因此可能存在问题。