UIManagedDocument与NSFetchedResultsController和后台上下文 [英] UIManagedDocument with NSFetchedResultsController and background context

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

问题描述

我试图让下列工作。

我有一个表视图,显示从一个API获取的数据在表视图。为此目的,我使用一个NSFetchedResultsController:

I have a table view that is displaying data fetched from an API in a table view. For that purpose I am using a NSFetchedResultsController:

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                        managedObjectContext:self.database.managedObjectContext
                                                                      sectionNameKeyPath:nil
                                                                               cacheName:nil];

我在背景环境中创建我的实体,如下:

I create my entities in a background context like this:

    NSManagedObjectContext *backgroundContext;
    backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    backgroundContext.parentContext = document.managedObjectContext; 

    [backgroundContext performBlock:^{
        [MyAPI createEntitiesInContext:backgroundContext];

        NSError *error = nil;
        [backgroundContext save:&error];
        if (error) NSLog(@"error: %@",error.localizedDescription);

        [document.managedObjectContext performBlock:^{
            [document updateChangeCount:UIDocumentChangeDone];
            [document.managedObjectContext save:nil];
        }];



现在,每当我获得新数据(和插入/更新实体,如上所示),我的NSFetchedResultsController不工作,因为它应该。特别是,我总是更新一个实体(不创建一个),但我的表视图显示两个实体。一旦我重新启动应用程序,它显示正确。

Now, whenever I get new data (and insert/update entities like shown just above), my NSFetchedResultsController doesn't quite work as it should. In particular, I am always updating one entity (not creating a new one), but my table view shows two entities. Once I restart the app it shows up correctly.

如果我在self.database.managedObjectContext中执行实体([MyAPI createEntities])的创建,一切正常。

If I perform the creation of the entities ([MyAPI createEntities]) in self.database.managedObjectContext, everything works fine.

任何想法我做错了什么?通过这里的现有线索SO使我认为我做的正确的方式。再次,如果我不做核心数据保存在后台上下文(但在document.managedObjectContext),那么它工作正常...

Any idea what I am doing wrong? Looking through the existing threads here on SO makes me think that I'm doing it the right way. Again, if I do not do the core data saves in the background context (but on document.managedObjectContext) then it works fine...

推荐答案

我今天在Apple开发论坛上看到了一个类似的问题。也许这与您的问题相同, https://devforums.apple.com/message/666492# 666492 ,在这种情况下可能有一个错误(或者至少有其他人有相同的问题来讨论它。)

I read about a similar problem on the Apple dev forums today. Perhaps this is the same problem as yours, https://devforums.apple.com/message/666492#666492, in which case perhaps there is a bug (or at least someone else with the same issue to discuss it with!).

假设它isn' t,它听起来像你想做的应该是完全可能的嵌套上下文,因此假设没有bug与 UIManagedDocument

Assuming it isn't, it sounds like what you want to do should be perfectly possible with nested contexts, and therefore assuming no bugs with UIManagedDocument.

我唯一的保留是我一直在尝试使用 UIManagedDocument 不适用于嵌套上下文( NSFetchRequest fetchBatchSize不能与UIManagedDocument 配合使用)。我认为 NSFetchedResultsController 的一个主要好处是它能够通过批量加载提高性能。所以如果这不能在 UIManagedDocument 中做,也许 NSFetchedResultsController 不能使用 UIManagedDocument 但我还没有到那个问题的底部。

My only reservation is that I've been trying to get batch loading working with UIManagedDocument and it seems like it does not work with nested contexts (NSFetchRequest fetchBatchSize does not work with UIManagedDocument). I would think one of the main benefits of NSFetchedResultsController is it's ability to improve performance through batch loading. So if this can't be done in UIManagedDocument perhaps NSFetchedResultsController isn't ready for use with UIManagedDocument but I haven't got to the bottom of that issue yet.

这个预留,我读过的大部分指令或查看有关嵌套上下文和后台工作似乎是用对等子上下文。你所描述的是父,子,孙的配置。在WWDC 2012视频会话214 - 核心数据最佳实践(+ 16:00分钟)中,Apple建议为此场景的父上下文添加另一个对等体上下文,例如

That reservation aside, most of the instruction I've read or viewed about nested contexts and background work seems to be done with peer child contexts. What you have described is a parent, child, grandchild configuration. In the WWDC 2012 video "Session 214 - Core Data Best Practices" (+ 16:00 minutes) Apple recommend adding another peer context to the parent context for this scenario, e.g

backgroundContext.parentContext = document.managedObjectContext.parentContext;

工作在此上下文中异步执行,然后通过调用保存到父级背景上下文。然后父对象将被异步保存,并且任何对等体上下文,在这种情况下 document.managedObjectContext ,将通过获取,合并或刷新访问更改。这也在 UIManagedDocument 文档中描述:

The work is performed asynchronously in this context and then pushed up to the parent via a call to save on the background context. The parent would then be saved asynchronously and any peer contexts, in this case the document.managedObjectContext, would access the changes via a fetch, merge, or refresh. This is also described in the UIManagedDocument documentation:


  • 你可以从后台线程直接加载数据
    到父上下文。您可以使用
    parentContext获取父上下文。将数据加载到父上下文意味着不要
    扰乱子上下文的操作。您可以通过执行抓取来检索在后台加载的
    数据。

  • If appropriate, you can load data from a background thread directly to the parent context. You can get the parent context using parentContext. Loading data to the parent context means you do not perturb the child context’s operations. You can retrieve data loaded in the background simply by executing a fetch.

:重读这可能只是建议Jeffery的建议,即不创建任何新的上下文,只使用父上下文。]

该文档还建议通常不调用保存在子上下文,但使用 UIManagedDocument 的保存方法。这可能是一个场合,当你打电话保存或可能部分的问题。如Jeffery所述,更不鼓励调用对父上下文的保存。我在堆栈溢出读取的另一个答案建议只使用 updateChangeCount 触发 UIManagedDocument 保存。但我没有从苹果读任何东西,所以也许在这种情况下,调用 UIManagedDocument saveToURL:forSaveOperation:completionHandler:方法将是适当的,以获得一切同步,保存。

That being said the documentation also suggests that typically you do not call save on child contexts but use the UIManagedDocument's save methods. This may be an occasion when you do call save or perhaps part of the problem. Calling save on the parent context is more strongly discouraged, as mentioned by Jeffery. Another answer I've read on stack overflow recommended only using updateChangeCount to trigger UIManagedDocument saves. But I've not read any thing from Apple, so perhaps in this case a to call the UIManagedDocument saveToURL:forSaveOperation:completionHandler: method would be appropriate to get everything in sync and saved.

我想下一个明显的问题是如何通知NSFetchedResultsController发生了更改。我会试图简化上面讨论的设置,然后订阅各种 NSManagedObjectContextObjectsDidChangeNotification 或保存在不同的上下文的通知,并看看,如果有,当 UIMangedDocument 保存,自动保存或后台更改保存到父级(假设在这种情况下允许)。我假设 NSFetchedResultsController 已连接到这些通知,以便与底层数据保持同步。

I guess the next obvious issue is how to notify NSFetchedResultsController that changes have occurred. I would be tempted to simplify the setup as discussed above and then subscribe to the various NSManagedObjectContextObjectsDidChangeNotification or save notifications on the different contexts and see which, if any, are called when UIMangedDocument saves, autosaves, or when background changes are saved to the parent (assuming that is allowable in this case). I assume the NSFetchedResultsController is wired to these notifications in order to keep in sync with the underlying data.

您需要在主上下文中手动执行提取,合并或刷新以获取通过的更改,然后以某种方式通知 NSFetchedResultsController 需要刷新?

Alternatively perhaps you need to manually perform a fetch, merge, or refresh in the main context to get the changes pulled through and then somehow notify NSFetchedResultsController that it needs to refresh?

个人我想知道 UIManagedDocument 是否准备好进行一般消费,今年没有提到它在WWDC,而是一个长时间讨论如何构建一个更复杂的解决方案:会话227 - 使用iCloud与核心数据

Personally I'm wondering if UIManagedDocument is ready for general consumption, there was no mention of it at WWDC this year and instead a lengthy discussion of how to build a much more complicated solution was presented: "Session 227 - Using iCloud with Core Data"

这篇关于UIManagedDocument与NSFetchedResultsController和后台上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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