我有一个带菜单项的UITableView,当菜单改变时,服务器将新列表推送到设备。当我添加菜单项时,显示列表的表视图会自动更新,或者在提交更改时更改它们。
但是,当我删除一个对象时,这不会反映在列表中(当我更改顺序时,也就是说,这意味着对象的'level'字段)。
这些更改仅在我完全关闭(终止)应用程序并重新启动后显示。
是否有一个简单的原因导致更新未被触发?
for(DOMenuItem* item in _oldMenuIdList){
[[self managedObjectContext] deleteObject:item];
}
NSError *error;
if(![[self managedObjectContext] save:&error]) {
NSLog(@"Error!");
}
[编辑:
@interface DOMenuItem : NSManagedObject {
}
@property (nonatomic, strong) NSNumber * id;
@property (nonatomic, strong) NSString * action;
@property (nonatomic, strong) NSString * title;
@property (nonatomic, strong) NSString * section;
@property (nonatomic, strong) NSNumber * level;
@property (nonatomic, strong) NSNumber * published;
@property (nonatomic, strong) NSString * icon;
@property (nonatomic, strong) NSDate * lastUpdate;
@property (nonatomic, strong) DOMenuItem * parent;
@property (nonatomic, strong) DOLang * language;
@property (nonatomic, strong) NSSet* children;
@property (nonatomic, strong) NSSet* groups;
@end
@interface DOMenuItem (CoreDataGeneratedAccessors)
- (void)addChildren:(NSSet *)value;
- (void)removeChildren:(NSSet *)value;
- (void)addGroups:(NSSet *)value;
- (void)removeGroups:(NSSet *)value;
- (void)addGroupsObject:(DOGroup *)value;
- (void)removeGroupsObject:(DOGroup *)value;
@end
-
- (NSFetchedResultsController *) createFetchedResultsController:(NSString*) cachName sectionString:(NSString*)sectionString sortBySection:(bool)sortBySection {
// Set up the fetched results controller (object who requests will own).
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:_objectName inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:_defaultSortField ascending:_sortAscending];
NSMutableArray *sortDescriptors = [[NSMutableArray alloc] init];
if(sortBySection && _sectionNameKeyPath != nil){
// Add section sorting at beginning
NSSortDescriptor *sortSectionDescriptor = [[NSSortDescriptor alloc] initWithKey:sectionString ascending:NO];
[sortDescriptors addObject:sortSectionDescriptor];
}
[sortDescriptors addObject:sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchLimit:0];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:sectionString cacheName:cachName];
//[sortDescriptors release];
return aFetchedResultsController;
}
- (NSFetchedResultsController*) findChildrenOfMenu:(DOMenuItem*) parentMenu {
NSPredicate* predicate;
if(parentMenu == nil){
predicate = [NSPredicate predicateWithFormat:@"(((ANY groups.validTime > %@) && (ANY groups.active == YES)) || (ANY groups.universal == YES)) && (parent == NULL) && (language.enabled == YES)", [NSDate date]];
//predicate = [NSPredicate predicateWithFormat:@"(parent == NULL)"];
} else {
predicate = [NSPredicate predicateWithFormat:@"(((ANY groups.validTime > %@) && (ANY groups.active == YES)) || (ANY groups.universal == YES)) && (parent == %@) && (language.enabled == YES)", [NSDate date], parentMenu];
}
[NSFetchedResultsController deleteCacheWithName:_cacheName];
NSFetchedResultsController* aFetchedResultsController = [self createFetchedResultsController:_cacheName sectionString:_sectionNameKeyPath sortBySection:YES];
[aFetchedResultsController.fetchRequest setPredicate:predicate];
[aFetchedResultsController.fetchRequest setFetchLimit:0];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:_defaultSortField ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[aFetchedResultsController.fetchRequest setSortDescriptors:sortDescriptors];
// Fetch the records and handle an error
NSError *fetchError;
if (![aFetchedResultsController performFetch:&fetchError]) {
// Handle the error.
// This is a serious error and should advise the user to restart the application
NSLog(@"Fetching data error: %@", [fetchError localizedDescription]);
}
return aFetchedResultsController;
}
[编辑2:] 在UIViewController中:
- (void)viewDidLoad
{
iDomsAppDelegate *delegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
// Get the menu's
_objects = [[[DOMenuItemsController alloc] init:[delegate managedObjectContext]] findChildrenOfMenu:(DOMenuItem*) _parentMenu];
[_objects setDelegate:self];
}
[编辑3:]
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)aSectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSUInteger sectionIndex = aSectionIndex;
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
NSLog(@"NEED TO LOOK AT THIS!");
break;
case NSFetchedResultsChangeUpdate:
NSLog(@"NEED TO LOOK AT THIS!");
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)aIndexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)aNewIndexPath {
UITableView *tableView = [self tableView];
switch(type) {
case NSFetchedResultsChangeInsert: {
//NSLog(@"Inserted!");
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:aNewIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
break;
case NSFetchedResultsChangeDelete:{
//NSLog(@"Delete");
// Skip if previous in section had same commonId
NSLog(@"Table delete... r:%li - s:%li", (long)aIndexPath.row, (long)aIndexPath.section);
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:aIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
break;
case NSFetchedResultsChangeUpdate:
//NSLog(@"Update menu");
[(DOPrototypeCell*) [tableView cellForRowAtIndexPath:aIndexPath] populateCell:[_objects objectAtIndexPath:aIndexPath]];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:aIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:{
//NSLog(@"Move");
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:aIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:aNewIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
@try {
[self.tableView endUpdates];
} @catch (NSException *exception) {
NSLog(@"Caught error on finding tabelview update: %@", exception.description);
[self.tableView reloadData];
}
[self checkViewheight];
}