在NSFetchedResultsController中更新/插入现有对象

时间:2010-12-01 18:00:48

标签: iphone objective-c core-data nsfetchedresultscontroller

我正在使用NSFetchedResultsController UITableView,其中显示该文件夹中每个项目的文件夹列表和相关的未读计数。我想在同步/刷新期间(在使用NSManagedObjectContextDidSaveNotification的后台线程上)根据未读计数从tableView插入/删除带动画的文件夹。没有未读项目的文件夹应该淡出,带有新未读项目的现有文件夹应该淡入。

目前使用controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:方法不会这样做,除非完全重新加载tableView,或重新启动应用程序,这是不理想的。

NSFetchedResultsController不是这样做的吗?我最初的想法是创建一个单独的Core Data实体,它只保存带有未读项目的文件夹,并添加/删除文件夹,但这看起来很糟糕。

我的NSPredicate看起来像是:

ANY items.unread == 1

更新 上面的NSPredicate运行良好,并抓住我期望它的对象。我的问题是,如果应用程序启动并且FolderX有0个未读项目,则不会显示。如果我然后刷新(出去并在后台线程中解析JSON文件)并且FolderX现在有25个未读项目,它将自动淡入或触发NSFetchedResultsChangeInsert,因为它不是' t包含在第一位,它也不会触发NSFetchedResultsChangeUpdate这就是为什么我认为解决方案是创建一个单独的实体,它只保存带有未读项目的文件夹,并在同步期间添加/删除它。

我只是觉得我错过了一些非常明显的东西。

更新2: 通过消除我自己的应用程序的影响,我尽可能地简化了问题,我能够在Xcode的默认Core Data模板中复制它。

新问题: 有一个名为“Event”的实体,没有关系和两个属性,“Date”和“unreadCount”。我使用NSPredicate设置了NSFetchedResultsController,如下所示:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"unreadCount < 10"];

每次添加一个新对象时,都会使用unreadCount 15创建它,然后所有现有对象都会减1.这是在一个单独的ManagedObjectContext上完成的(复制后台处理,但都是在主线程上完成的) )。

我已经实现了controllerWillChangeContent和相关的方法,我期望发生的是在现有对象(unreadCount为15)减少5次(现在为10)之后它应该插入到tableView中,因为它现在匹配谓词。这根本不会发生,除非重新启动应用程序,否则对象根本不会出现。

我已经附加了一个示例项目,只需运行它并单击Add按钮几次(不会发生任何事情)。重新启动应用程序,您将在tableView中看到一些对象,如果再单击“添加”按钮,这些对象将自行删除,但不会添加新对象。

如果NSFetchedResultsController不是使这种行为起作用的解决方案,那么它是什么?

示例项目:http://dl.dropbox.com/u/521075/BGUpdating.zip

1 个答案:

答案 0 :(得分:1)

您的谓词不会跨越两个或更多对话关系。你现在有:

type == folder AND ANY (set of folders).(set of items).unread == 1

您不能使用ANY来横向任意数量的关系。相反,您可能需要subquery之类的:

type == folder AND (0!=SUBQUERY(folder,$f,0!=SUBQUERY($f.items,$i,$i.unread==1).@count).@count)

我想你可能会对错误的实体进行抓取。如果要显示Folder个对象的表,则应该在Folder实体上执行提取。仅这一点就可以简化一切。你的谓词就是:

ANY items.unread==1