我有一个由UITableView填充的NSFetchedResultsController。最初的提取工作正常。我可以添加、删除、修改等零问题。但我想在表中添加用户定义的排序。为此,我将NSFetchedResultsController更改为使用不同的sortDescriptor集和不同的sectionNameKeyPath。这是我更改获取的代码:

-(void)changeFetchData {
    fetchedResultsController = nil;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    NSString *sortKey = @"sortKey";
    NSString *cacheName = @"myNewCache";
    BOOL ascending = YES;

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:sortKey cacheName:nil];
    self.fetchedResultsController = aFetchedResultsController;
    fetchedResultsController.delegate = self;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Fetch failed");
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

    [self.tableView reloadData];
}

当我调用这个方法时,它工作得很好。该表立即重新命令自己使用新的区段信息和新的排序参数。但是如果我向数据中添加或删除项,TableView不会更新其信息,从而导致崩溃。我可以在FETCHEDDREST控制器中对对象总数进行计数,并查看它的增加(和减少),但是如果我记录了numberOfRowsInSection的返回值来监视那里的变化,方法就会被调用,但是值不会改变。获取以下崩溃(用于添加,但删除的崩溃与此类似)
无效更新:第2节中的行数无效。更新(3)之后包含在现有部分中的行数必须等于更新之前(3)中包含的那一行的行数,加上或减去从该段插入或删除的行数(插入1,删除0)。带用户信息(空)
如果我重新启动应用程序,我将看到添加的项,或者看不到删除的项,因此我将正确修改数据源。
有什么想法吗?

最佳答案

可能旧控制器还活着。如果是这样,它可能仍然调用TableView控制器作为其委托,并使用自己的数据激活表更新。
我建议将获取的results controller对象记录到numberOfRowsInSection中,以确认它使用了新的控制器。在分配新控制器之前,应该将旧控制器的委托设置为nil。

07-28 02:37
查看更多