菜鸟教程小白 发表于 2022-12-13 05:43:28

ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller


                                            <p><p>我正在编写一个使用许多 <code>NSFetchedResultsControllers</code> (FRC) 的应用程序,每个应用程序用于我的数据模型中的不同托管对象子类。其中几个 FRC 是 <code>UITableViewControllers</code> 的一部分,但有几个不是。我有两个问题:第一,当我向 MOC 添加新对象时,为什么我的一个 FRC 没有更新,第二,我是否应该为此目的使用 FRC?我认为它可以让我不必在整个代码中放置获取请求,但也许只有将 FRC 与 <code>tableview</code> 或其他此类对象一起使用才有意义。 </p>

<p>所以,这里是详细信息。</p>

<p>不绑定(bind)到 <code>tableview</code> 的 FRC 之一是跟踪时间表的 FRC。 SetScheduleViewController 具有以下属性(以及其他属性),这些属性是通过父 ViewController 传入的:</p>

<pre><code>@property (weak, nonatomic) NSFetchedResultsController *scheduleFetchedResultsController;
@property (weak, nonatomic) NSManagedObjectContext *managedObjectContext;
</code></pre>

<p>这个 FRC 是由另一个对象(它维护一个指向它的强指针)通过以下代码创建的</p>

<pre><code>- (NSFetchedResultsController *)scheduleFetchedResultsController{


    if (_scheduleFetchedResultsController != nil) {
      return _scheduleFetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [ init];

    NSEntityDescription *entity = ;

    ;

    // Set the batch size to a suitable number.
    ;

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [ initWithKey:@&#34;start&#34; ascending:NO];
    NSArray *sortDescriptors = @;

    ;

    NSFetchedResultsController *fRC = [ initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];


    NSError *error = nil;
    if (!) {
      IFLErrorHandler *errorHandler;
      ;
      NSLog(@&#34;Unresolved error %@, %@&#34;, error, );
      abort();
    }

    self.scheduleFetchedResultsController = fRC;

    return self.scheduleFetchedResultsController;
}
</code></pre>

<p>(顺便说一句:cacheName 设置为 nil 的原因是我似乎只能将缓存名称分配给此应用程序中的众多 FRC 中的一个,或者应用程序崩溃......如果只有一个 FRC给定一个缓存名称,其余的缓存名称设置为 nil,一切似乎都很好,尽管我担心没有缓存,随着持久存储大小的增长,性能可能会很糟糕......但这是另一回事)</p >

<p>在<code>SetScheduleViewController</code> 中,可以创建或删除一个计划,并在加载<code>SetScheduleViewController</code> 时加载最近创建的计划。创建计划时,会创建一个新的计划管理对象,然后将 MOC 保存如下:</p>

<pre><code> Schedule *newSchedule= ;
newSchedule.start=newStartTime;
//etc

NSError *saveError;
    if (!) {
      // Replace this implementation with code to handle the error appropriately.
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      NSLog(@&#34;Unresolved error %@, %@&#34;, saveError, );
      abort();
</code></pre>

<p>这成功保存了新的 MO,但 FRC 没有更新...我已经检查了几种方法...例如,如果在保存新计划后我重新输入 <code>SetScheduleViewController</code> 并检查 <code>[</code> count] 它没有增加。但是,如果我退出应用程序并再次打开它,你瞧,FRC 获取的对象计数会增加,并且新对象确实存在。 </p>

<p>我应该注意到 <code>scheduleFetchedResultsController</code> 没有分配委托(delegate),这与 FRC 附加到 <code>tableviewcontrollers</code> 不同,它们都可以正常工作。我没有分配委托(delegate),因为据我所知,<code>tableviewcontrollers</code> 中的 FRC 委托(delegate)方法仅在 FRC 更改内容时处理更新 tableview...我没有看到任何委托(delegate)方法添加新对象并保存 MOC 时刷新 FRC 本身。</p>

<p>所以,我的两个问题又是:1) 为什么 FRC 不刷新(以及我如何让它刷新),2) 使用 FRC 来管理未绑定(bind)的托管对象的获取结果是否有意义到 <code>tableview</code>,我是否应该在每次需要访问对象列表时简单地从 MOC 执行新的提取?</p>

<p>非常感谢任何帮助。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>在 <code>NSFetchedResultsController</code> 文档中指出,如果没有设置委托(delegate),FRC 处于“无跟踪”模式。此外,委托(delegate)必须至少实现一种变更跟踪委托(delegate)方法才能启用变更跟踪。 </p>

<p>委托(delegate)不必是表格 ViewController ,因此您可以使用您的
<code>SetScheduleViewController</code> 作为委托(delegate),只需实现 <code>controllerDidChangeContent:</code> 委托(delegate)方法。在该方法中,更新的
<code>fetchedObjects</code> 是可用的,你可以例如更新 View 中的任何 UI 元素
Controller 。</p>

<p><em>更新:</em>从 parentVC 传递 FRC 没有多大意义。 <em>每个 ViewController 都应该有自己的 FRC</em>。所以 <code>scheduleFetchedResultsController</code> 应该是 childVC 中的一个方法。由于 FRC 是在 getter 方法中“延迟”创建的,因此必须在某个地方调用 getter。</p>

<p>在 TableViewController 的情况下,发生这种情况是因为所有 TableView 数据源方法
访问 <code>self.fetchedResultsController</code>。</p>

<p>如果您的 childVC 不访问 <code>self.fetchedResultsController</code> 那么 FRC
不会被创建。这可能是在 <code>viewDidLoad</code> 中调用 <code></code> 的原因,正如另一个答案中所建议的那样,解决了您的问题。</p>

<p>委托(delegate)方法 <code>controllerDidChangeContent:</code> 如果结果会被调用
<em>在 childVC 的生命周期内设置更改</em>。这就是使用 FRC 的意义所在。</p>

<p>如果您只想在加载 childVC 时获取当前对象集,那么
你不需要 FRC,你可以执行一个简单的 fetch,例如在 <code>viewDidLoad</code>.</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/20604490/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/20604490/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller