菜鸟教程小白 发表于 2022-12-12 10:59:57

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


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

<p>代码如下:</p>

<pre><code>-(void)updateLayers{
    for (int i = 0; i &lt; ; i++) {
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i
                                                    inSection:0];
            ((Layer *)).layer.position = i;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    ;
    ;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><code>NSFetchedResultsControllerDelegate</code> 中的所有<code>willChange</code>/<code>didChange</code> 方法都是在你修改Core Data 对象后调用的。所以如果你修改了<code>controllerDidChangeContent:</code>里面的任何<code>NSManagedObject</code>,都会再次触发<code>controllerDidChangeContent:</code>,导致死循环。</p>

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

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

<p>所以你可能想做这样的事情:</p>

<pre><code>//in the method in which you add a new Layer object
- (void)addLayer {
Layer *layer = ;
//recalculate the position of all the other layers
//save NSManagedObjectContext
}
</code></pre>

<p>关键是添加新层后立即更新每一层的<code>position</code>,然后保存上下文。然后 <code>NSFetchedResultsController</code> 将按照您的需要将图层的位置“绑定(bind)”到表中的行(我假设您在使用的排序描述符中使用 <code>position</code> 属性在获取请求中)。如果您按照 <a href="https://developer.apple.com/library/iOs/documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSFetchedResultsControllerDelegate/controllerDidChangeContent:" rel="noreferrer noopener nofollow">documentation</a> 中的建议实现这些 <code>NSFetchedResultsControllerDelegate</code> 方法,它应该做的工作:</p>

<pre><code>- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    ;
}

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

    UITableView *tableView = self.tableView;

    switch(type) {

      case NSFetchedResultsChangeInsert:
            
                     withRowAnimation:UITableViewRowAnimationFade];
            break;

      case NSFetchedResultsChangeDelete:
            
                     withRowAnimation:UITableViewRowAnimationFade];
            break;

      case NSFetchedResultsChangeUpdate:
            
                  atIndexPath:indexPath];
            break;

      case NSFetchedResultsChangeMove:
            
                     withRowAnimation:UITableViewRowAnimationFade];
            
                     withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    ;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/25103478/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/25103478/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环