5

我有一个UITableViewNSFetchedResultsController. 初始提取工作正常。我可以零问题地添加、删除、修改等。但我想将用户定义的排序添加到表中。我通过更改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 不会更新其信息,从而导致崩溃。我可以 NSLog 获取 fetchedResultsController 中的对象总数的计数,并看到它增加(和减少),但如果我 NSLog 返回值numberOfRowsInSection以监视那里的变化,则调用该方法,但值不会改变。得到以下崩溃(用于添加,但删除类似)

无效更新:第 2 节中的行数无效。更新后现有节中包含的行数 (3) 必须等于更新前该节中包含的行数 (3),加上或减去数字从该部分插入或删除的行数(插入 1 行,删除 0 行)。与用户信息(空)

如果我重新启动应用程序,我会看到添加的项目,或者看不到删除的项目,因此我正在正确修改数据源。

有任何想法吗?

4

2 回答 2

2

旧控制器可能仍然存在。如果是这样,它可能仍将 tableview 控制器作为其委托调用并使用它自己的数据激活表更新。

我建议记录获取的结果控制器对象numberOfRowsInSection以确认它使用新控制器。在分配新控制器之前,您应该将旧控制器的委托设置为 nil。

于 2010-07-16T19:26:59.803 回答
0

有一次,添加:

- (void)viewDidDisappear:(BOOL)animated
{     
 self.fetchedResultsController.delegate = nil;
}

解决了当行数更改但保存的数据仍然不同且不是最新时出现的类似问题。

于 2013-09-05T15:33:13.137 回答