菜鸟教程小白 发表于 2022-12-12 20:20:11

ios - NSFetchedResultsController无法在子上下文中获取


                                            <p>我有一个<code>UIManagedDocument</code>,其中包含一些数据,这些数据会使用<code>NSFetchedResultsController</code>在列表中显示。数据会在后台定期更新,并将更改放入<code>UIManagedDocument.managedObjectContext</code>(使用performBlock :)。<br><br>当我显示来自文档主要上下文的数据时,所有工作均按预期进行。但是,一旦我在主上下文(<code>child.parentContext = document.managedObjectContext</code>)的子上下文中显示列表,我就看不到任何对象,并且控制台上会显示以下错误:<br><pre><code>foo CoreData: error: (NSFetchedResultsController)
               The fetched object at index 5 has an out of order section name &#39;E.
               Objects must be sorted by section name&#39;
</code></pre><br>这仅在将新对象插入文档联系人后才发生。当我等待足够长的时间以进行自动保存时,列表显示正常。另外,问题仅在于当我在<code>sectionNameKeyPath</code>上设置了<code>NSFetchedResultsController</code>且仅具有子上下文时。<br><br>这是我设置获取的结果控制器的方式,没什么花哨的,所以在这里我看不到我会做错什么:<br><pre><code>NSFetchRequest *fetchRequest = [ initWithEntityName:@&#34;Contact&#34;];
fetchRequest.sortDescriptors = ;
fetchRequest.predicate = ;

NSFetchedResultsController *fetchedResultsController =
[ initWithFetchRequest:fetchRequest
                                    managedObjectContext:_managedObjectContext
                                    sectionNameKeyPath:
                                             cacheName:@&#34;ContactList&#34;];
</code></pre><code></code>和<code></code>在运行时解析。排序描述符包含sectionNameKeyPath作为第一个条目。 <code>nil</code>或其他有趣的东西都不能。<br><br> <strong>编辑</strong>:澄清了一些模糊的部分。具体来说,我不会在文档托管对象上下文中调用-save:。<br><br> <strong>编辑2 </strong>:我将尝试解释MOC之间的关系。<br><br>有三种受管对象上下文在起作用:<br><br>1)通过加载文档创建的<code>UIManagedDocument.managedObjectContext</code>。<br><br>2)运行一个后台线程,该线程不时更新对象。这是一个以文档MOC为父文档的 private 队列moc:<br><pre><code>context = [ initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = repository.managedObjectContext;

;
; }];
</code></pre><br>3)当用户要进行更改时,将创建一个新的MOC作为文档MOC的子代。这是主队列MOC。这是用于执行上面显示的提取的上下文。<br><br>后台更新是通过NSOperationQueue完成的,但是所有对后台MOC的访问都被<code>-performBlock:</code>正确地包围了。所有其他访问均从主线程完成。<br><br> <strong>编辑3 </strong>:在对<code>NSFetchRequest</code>进行一些设置时,我发现设置<code>fetchRequest.includesPendingChanges = NO</code>时问题消失了。但这不是一个可行的解决方案,因为在UIManagedDocument将更改保存到后台之前,用户现在看不到任何更新。</p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p>这里有几个危险信号给我。首先,这个...<br><br>数据会在后台定期更新,并将更改保存到UIManagedDocument.managedObjectContext中(使用performBlock :)。<br><br>UIManagedDocuments实现了自动保存,并且唯一应该直接调用save方法的时间是在初始创建时。所有其他“保存”都应通过自动保存界面来完成。基本上,这就是<br><pre><code>;
</code></pre><br>如果您使用UndoManager,这将自动完成。因此,如果您直接输入document.managedContext,您要做的就是调用上述方法来通知托管文档更改已完成,其他所有操作均应自动处理。<br><br>其次,我不确定您的意思是什么:<br><br>但是,一旦我在子上下文中显示列表,<br><br>孩子的上下文是什么?为什么任意上下文会看到任何东西?它是UIManagedDocument主要上下文的子上下文,还是父级,还是其他?<br><br>该文档很清楚(对于某些明确的定义),但是不幸的是,它需要阅读UIDocument,UIManagedDocument和所有NSManagedOjectContext的完整文档集。<br><br>当我终于把头放在发生的事情上(具有讽刺意味的是,通过阅读有关iCloud的工作方式来阅读)时,与UIManagedDocument相关的所有问题似乎都消失了。<br><br>基本上,请遵循以下简单规则:<br><li>从不直接在UIManagedDocument中嵌入的任何上下文上调用任何“保存”方法。 </li><li>当对象是“脏”的并且需要保存时,可以使用撤消管理器注册更改,或者直接调用。 </li><li>如果要使用子上下文,请继续。在这种情况下,您需要做的就是设置parentContext属性,然后在您的子上下文上调用save:。其他一切将自动发生。 </li><br> <strong>编辑</strong><br>另一个危险信号是您正在使用不同的上下文运行代码。如果是这种情况,则必须确保从正确的线程运行。 NSManagedObjectContext对象不是线程安全的。因此,必须始终从创建它们的线程中访问它们(如果为NSConfinementConcurrencyType),或者如果是其他两种并发类型之一,则必须使用performBlock进行访问。<br><br>如果要使用多个上下文连续进行插入/获取操作,将需要解决一些问题。主要是,您必须确保所做的更改已传播并计划保存,然后,您的提取操作才可以执行。<br><br>插入完成后,请确保仅使用UIManagedDocument的子上下文调用save。切勿在托管文档上调用save或saveToURL。使用上述方法将其保存。这将确保您正确传播更改。<br><br>提取时,您必须决定是否要让提取一直沿上下文链进行。 NSFetchRequest上有很多选项(例如setShouldRefreshRefetchedObjects)。这些选项将决定获取是否仅使用其自身的上下文,还是进入后备存储,以及其他很多东西。默认值通常是您想要的,但是使用子上下文时,您承担的责任更大。<br><br>另外,如果您有子上下文,则必须确保使用正确的并发类型创建它们,并且仅在适当的线程/队列中使用它们。否则,您将获得不确定的结果。<br><br> <strong>编辑</strong><br><br>为了回应您最近提出的问题,请编辑以下语句:<br><br>3)当用户要进行更改时,将创建一个新的MOC作为文档MOC的子代。这是主队列MOC。这是用于执行上面显示的提取的上下文。<br><br>我从未做过,对我来说,是另外一个危险信号。已经有一个主队列MOC-document.managedObjectContext。如果要在主线程中处理文档,请使用该选项。记住,CoreData仍然在线程包含模型上运行,并且实际上每个线程只需要一个MOC。新的API提供了使MOC与队列相关联的方法,并提供了帮助,但是我敢打赌,每个线程有多个MOC会引起问题。通常,我会避免这种情况。</p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSFetchedResultsController无法在子上下文中获取,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/10188319/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/10188319/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSFetchedResultsController无法在子上下文中获取