ios / core data / nsfetchedresultscontroller。如何在添加新记录后获取要更新的记录的tableview

时间:2015-03-18 16:32:00

标签: ios nsfetchedresultscontroller

我正在尝试使用委托模式在添加新记录后获取要更新的记录的tableview。

我在tableview控制器中有nsfetched结果控制器的代码。该表被订阅为nsfetchedresults控制器的委托。我在添加新记录控制器中有保存代码。我究竟做错了什么?谢谢。

table view controller:
header:
@interface IDTVC : UITableViewController<UITableViewDataSource, UITableViewDelegate,NSFetchedResultsControllerDelegate>

source:
#pragma mark - Fetched Results Controller

-(NSFetchedResultsController *)fetchedResultsController {
    if (_fetchedResultsController==nil){
        NSFetchRequest *fetchRequest= [[NSFetchRequest alloc] init];
        //access the single managed object context through model singleton
        NSManagedObjectContext *context = [IDModel sharedInstance].managedObjectContext;
        //fetch request requires an entity description - we're only interested in IDModel managed objects
        NSEntityDescription *entity =[NSEntityDescription entityForName:@"Dare" inManagedObjectContext:context];
        fetchRequest.entity=entity;
        //we'll order the IDModel ID Model objects in name sort order
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil];
        fetchRequest.sortDescriptors=sortDescriptors;

        self.fetchedResultsController=[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
 //       self.fetchedResultsController.delegate=self;

        [self.fetchedResultsController setDelegate:self];

        NSError *error = nil;
        if (![self.fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@,%@",error,[error userInfo]);
        abort();
    }

    }
    return _fetchedResultsController;
}
//following supposed to be sufficient for delegate pattern to work
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
//change
}

AddRecord Controller

- (IBAction)save:(id)sender {

    self.managedObjectContext = [IDModel sharedInstance].managedObjectContext;;
    // Helpers

    NSString *name = self.textField.text;
    NSString *sub = self.subField.text;

 //    [[[UIAlertView alloc] initWithTitle:name message:@"Your record needs a name." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    NSLog(@"save triggered");
    if (name && name.length) {
        // Create Entity
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"newitem" inManagedObjectContext:self.managedObjectContext];

        // Initialize Record
        NSManagedObject *record = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];

        // Populate Record
        [record setValue:name forKey:@"name"];
        [record setValue:sub forKey:@"sub"];

     //   [record setValue:[NSDate date] forKey:@"createdAt"];

        // Save Record
        NSError *error = nil;

        if ([self.managedObjectContext save:&error]) {
            // Dismiss View Controller
            [self dismissViewControllerAnimated:YES completion:nil];
            ;


        } else {
            if (error) {
                NSLog(@"Unable to save record.");
                NSLog(@"%@, %@", error, error.localizedDescription);
            }

            // Show Alert View
            [[[UIAlertView alloc] initWithTitle:@"Warning" message:@"Your record could not be saved." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        }

    } else {
        // Show Alert View
        [[[UIAlertView alloc] initWithTitle:@"Warning" message:@"Your item needs a name." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    }
}
//dismiss keyboard
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"touchesBegan:withEvent:");
    [self.view endEditing:YES];
    [super touchesBegan:touches withEvent:event];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"Add Item";
    [IDModel sharedInstance];

    self.managedObjectContext = self.managedObjectContext;
}

我需要[self.tableView reloadData];某处或不应该委托模式处理更新?

将保存添加到视图控制器和表视图中的nsfetchresultscontroller代码是否有问题?非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

除了controllerDidChangeContent委托方法之外,您还需要controllerWillChangeContent,它将启动表视图更新。然后在controllerDidChangeContent中,您将不得不在表视图上结束更新。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[tableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[tableView endUpdates];
} 

您还需要另一个实际处理每个更新操作的委托方法。下面:

-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
 switch (type)
{
    case NSFetchedResultsChangeUpdate:
        [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.row] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;

    case NSFetchedResultsChangeInsert:
        [tableView insertSections:[NSIndexSet indexSetWithIndex:newIndexPath.row] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;

    case NSFetchedResultsChangeDelete:
        [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.row] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;

    case NSFetchedResultsChangeMove:
        [tableView moveSection:indexPath.row toSection:newIndexPath.row];
        break;

    default:
        NSAssert(FALSE, @"what is this?");
        break;
}
}

答案 1 :(得分:0)

好的,编辑没有通过...使用Lee的答案,但添加了第四个FetchedResultsControllerDelegate方法:

- (void)controller:(NSFetchedResultsController *)controller
    didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
        atIndex:(NSUInteger)sectionIndex
            forChangeType:(NSFetchedResultsChangeType)type
{
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionIndex];

    switch(type)
    {
        case NSFetchedResultsChangeInsert:
        {
            [self.tableView insertSections:indexSet
                withRowAnimation:UITableViewRowAnimationFade];
            break;
        }
        case NSFetchedResultsChangeDelete:
        {
            [self.tableView deleteSections:indexSet
                withRowAnimation:UITableViewRowAnimationFade];
            break;
        }
        default:
        {
            [self.tableView reloadSections:indexSet
                withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
        }
    }
}