需要澄清NSFetchedResultsController和NSFetchedResultsControllerDelegate [英] Needed clarifications for NSFetchedResultsController and NSFetchedResultsControllerDelegate

查看:185
本文介绍了需要澄清NSFetchedResultsController和NSFetchedResultsControllerDelegate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在SO中,有很多关于 NSFetchedResultsController 和委托的问题/回复。有时代表触发,有时不触发。因为Core Data是相当复杂的参数,很难理解发生了什么,而不花费大量的时间。


有几个已知的问题和行为更改
与NSFetchedResultsController在各版本的iOS上。


因此,我需要一些澄清这种类的行为。特别地,从文档中写有以下内容:


因此,控制器有效地具有三种操作模式,确定
是否有委托以及是否设置了缓存文件名。



无跟踪:委托设置为nil。控制器只需
就可以访问数据,就像执行提取操作时一样。



仅内存跟踪:代理是非零,文件高速缓存名称
设置为nil。控制器监视其结果集中的对象,并且响应相关的
更改,
更新节和订单信息。



完全持续跟踪: 委托和文件缓存名称为
非零。控制器监视其结果集中的对象,并更新
部分和订购信息以响应相关更改。
控制器保持其
计算结果的持久高速缓存。


复杂的应用程序,我利用 NSFetchedResultsController 从商店检索数据并将其显示在表中。
显示的托管对象有一个 syncStatus 布尔变量,以验证它们是否已与外部服务同步。 syncStatus 变量未显示在单元格中,显示不同的信息(例如文本值)。换句话说, syncStatus 不会触发为错误。



在表中,通过 NSFetchedResultsController ,我只显示未同步的元素(bool值设置为 NO )。

   - (NSFetchedResultsController *)fetchedResultsController 
{
if(_fetchedResultsController)
return _fetchedResultsController;

NSManagedObjectContext * mainContext = [self managedObjectContext];

NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@LocalEntityinManagedObjectContext:mainContext]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@syncStatus ==%@,[NSNumber numberWithBool:NO]]];
[fetchRequest setFetchBatchSize:10];

// sort descriptor here ...

_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;

return _fetchedResultsController;
}

用户可以选择她/他想要同步的元素和后台线程将所选元素发送到服务,对于这些,还将 syncStatus 变量更改为 YES



当操作完成后,由于我设置 NSFecthedResultsControllerDelegate ,我注册 NSManagedObjectContextDidSaveNotification 我也在主线程中合并通过通知的更改我可以看到通知包含具有正确更改的对象),我希望表更新(将不显示 syncStatus 设置为 YES 的对象。



现在的问题如下。



根据doc,由于我使用仅内存跟踪选项,缺少更新是由于事实 isSyncStatus 未在内存上加载,但它仍然是一个错误?



/ p>

NSFetchedResultsControllerDelegate 方法正确实现。

解决方案

您正在实施 NSFetchedResultsControllerDelegate

   - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {

[self.tableView beginUpdates]; (NSFetchedResultsChangeType)类型newIndexPath:(NSIndexPath *)newIndexPath(NSIndexPath *)newIndexPath(NSIndexPath *)newIndexPath(NSIndexPath *)newIndexPath(NSFetchedResultsController *)控制器didChangeObject: {

UITableView * tableView = self.tableView;

switch(type){
case NSFetchedResultsChangeDelete:

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

[self.tableView endUpdates];
}


Within SO there are a lot of questions/replies about NSFetchedResultsController and delegate. Sometimes the delegate fires, sometimes not. And since Core Data is quite complex argument is quite difficult to understand what is going on without spending a lot of time on it. In addition, the documentations says that there are several problems but it does not list them.

There are several known issues and behavior changes with NSFetchedResultsController on various releases of iOS.

Hence, I need some clarifications about the behavior of such a class. In particular, from the documentation there is written the following:

A controller thus effectively has three modes of operation, determined by whether it has a delegate and whether the cache file name is set.

No tracking: the delegate is set to nil. The controller simply provides access to the data as it was when the fetch was executed.

Memory-only tracking: the delegate is non-nil and the file cache name is set to nil. The controller monitors objects in its result set and updates section and ordering information in response to relevant changes.

Full persistent tracking: the delegate and the file cache name are non-nil. The controller monitors objects in its result set and updates section and ordering information in response to relevant changes. The controller maintains a persistent cache of the results of its computation.

I'm developing a quite complex app and I'm taking advantage of NSFetchedResultsController to retrieve data from a store and display them in a table. Displayed managed objects have a syncStatus boolean variable to verify if they have been synced with an external service or not. syncStatus variable is not displayed in a cell, different info are displayed (e.g. text values). In other words, syncStatus is not fired as fault.

In the table, by means of NSFetchedResultsController, I display the only elements that are not synced (the bool value is set to NO).

- (NSFetchedResultsController*)fetchedResultsController
{
    if(_fetchedResultsController)
        return _fetchedResultsController;

    NSManagedObjectContext* mainContext = [self managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"LocalEntity" inManagedObjectContext:mainContext]];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"syncStatus == %@", [NSNumber numberWithBool:NO]]];
    [fetchRequest setFetchBatchSize:10];

    // sort descriptor here...

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil];
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

The user can select the elements she/he wants to sync and a background thread sends the selected elements to the service and, for those, it also changes the syncStatus variable to YES.

When the operation is finished, since I set the NSFecthedResultsControllerDelegate and I register for NSManagedObjectContextDidSaveNotification (I also merge in the main thread the changes through the notification. I'm able to see that the notification contains objects with the correct change), I expect the table is updated (the objects with syncStatus set to YES would be not displayed).

Said this, the question is the following.

Based on doc, since I use the Memory-only tracking option, does the missing update is due to the fact isSyncStatus is not loaded on memory but it remains a fault?

Could you suggest me in the right direction?

Thank you in advance.

P.S.

NSFetchedResultsControllerDelegate methods are implemented correctly. Doing the same only in main thread works.

解决方案

Are you implementing the NSFetchedResultsControllerDelegate methods to remove the cell?

- (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 NSFetchedResultsChangeDelete:

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

    [self.tableView endUpdates];    
}

这篇关于需要澄清NSFetchedResultsController和NSFetchedResultsControllerDelegate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆