【问题标题】:UITableView not updating DataSource after change to NSFetchedResultsController更改为 NSFetchedResultsController 后 UITableView 未更新 DataSource
【发布时间】:2010-07-16 16:31:08
【问题描述】:

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

-(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 以监视那里的变化,则调用该方法,但值不会t 改变。得到如下崩溃(添加,但删除类似)

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

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

有什么想法吗?

【问题讨论】:

    标签: iphone objective-c uitableview nsfetchedresultscontroller nsfetchrequest


    【解决方案1】:

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

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

    【讨论】:

    • 我会被诅咒的。设置self.fetchedResultsController.delegate = nil 解决了这个问题。将委托设置为零会更好吗?还是我应该尝试完全杀死它?
    • 由于委托是你的视图控制器本身,你可以杀死它。问题不在委托中,而是因为旧的 FRC 仍然存在并通过发送视图控制器 FRC 委托消息来响应数据模型中的更改而发生。重要的是要记住 release 不会杀死对象,它只是告诉对象 A 对象 B 不再需要它。如果对象 A 有其他保留,它可以挂起。
    【解决方案2】:

    有一次,添加:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 2011-11-23
      相关资源
      最近更新 更多