gpt4 book ai didi

ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:04:30 24 4
gpt4 key购买 nike

我有 UITableViewController 表并使用 NSFetchedResultsController 从核心数据中获取行。我的 tableView 负责分层数据。每个行位置代表层(在零行最高层,n - 行最低)。假设我们有名称为 Layers *layers 的对象。当我创建新层时,它需要转到表中的第一行 (indexPath.row == 0) 并需要获取 layers.layer.position = 0。当我创建新层或进行其他一些更改(移动、删除)时,我需要刷新核心数据对象 layers(每个层都需要获得新的位置值)。但是,如果我通过调用 [self updateLayersPosition] 方法来刷新图层位置 controllerDidChangeContent 方法,它会进入无限循环,因为每次在每个旧图层值更改时它都会返回到相同的 controllerDidChangeContent 方法一次又一次。所以问题是如何将表行或获取的 Controller indexPath.rowlayers.layer.position“绑定(bind)”?也许我可以找到一些方法来阻止 fetchedresultscontroller 获取,进行更新然后再次开始获取?或者也许还有其他方法可以做到这一点?

代码如下:

-(void)updateLayers{
for (int i = 0; i < [self.tableView numberOfRowsInSection:0]; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i
inSection:0];
((Layer *)[self.fetchedResultsController objectAtIndexPath:indexPath]).layer.position = i;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self updateLayers];
[self.tableView endUpdates];
}

最佳答案

NSFetchedResultsControllerDelegate 中的所有willChange/didChange 方法都会在您修改Core Data 对象后调用。因此,如果您在 controllerDidChangeContent: 中修改任何 NSManagedObject,它将再次触发 controllerDidChangeContent:,从而导致无限循环。

您可以将这些委托(delegate)回调视为 Controller 说“您已经更改了核心数据模型中的某些内容,现在让我们更新 UI(UITableView)。您应该遵循的一般模式是:

  • NSManagedObjects 中进行一项或多项更改(添加、修改、删除)
  • 保存NSManagedObjectContext
  • NSFetchedResultsControllerDelegate 的方法中:更新 UITableView 以反射(reflect)更改(添加、重新加载、删除 TableView 行)

所以你可能想做这样的事情:

//in the method in which you add a new Layer object
- (void)addLayer {
Layer *layer = [NSEntityDescription insertNewObjectForEntityForName:@"Layer" inManagedObjectContext:context];
//recalculate the position of all the other layers
//save NSManagedObjectContext
}

关键是在添加新图层后立即更新每个图层的位置,然后保存上下文。然后 NSFetchedResultsController 将负责将层的位置“绑定(bind)”到表中的行,如您所愿(我假设您在使用的排序描述符中使用 position 属性在获取请求中)。如果您按照 documentation 中的建议实现这些 NSFetchedResultsControllerDelegate 方法,它应该做的工作:

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

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;

case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}


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

关于ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25103478/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com