如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController

Posted

技术标签:

【中文标题】如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController【英文标题】:How to be sure NSFetchedResultsController is notified after background thread save with MagicalRecord 3.0 【发布时间】:2014-07-19 22:02:19 【问题描述】:

我正在使用带有 ClassicWithBackgroundCoordinatorSQLiteMagicalRecordStack 堆栈和 NSFetchedResultsController 的 MagicalRecord 3.0。在 Magical Record 使用后台线程(通过[MagicalRecord saveWithBlock:])保存新的相关数据后,NSFetchedResultsController 没有更新的问题。

栈就这样初始化了:

    MagicalRecordStack *stack = [[ClassicWithBackgroundCoordinatorSQLiteMagicalRecordStack alloc] initWithStoreNamed:@"Mailstrom.sqlite"];
    [MagicalRecordStack setDefaultStack:stack];

NSFetchedResultsController 初始化如下:

    NSFetchRequest *request = [NSClassFromString(_entityName)
                               MR_requestAllSortedBy:_weightProperty
                               ascending:NO
                               withPredicate:[NSPredicate predicateWithFormat:@"%K>%d", _weightProperty, 0]];

    request.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:_weightProperty ascending:NO] ];

    _fetchedResultsController = [[NSFetchedResultsController alloc]
                                     initWithFetchRequest:request
                                     managedObjectContext:[[MagicalRecordStack defaultStack] context]
                                     sectionNameKeyPath:nil
                                     cacheName:nil];

    self.fetchedResultsController.delegate = self;
    [_fetchedResultsController MR_performFetch];

偶尔会提取通过[MagicalRecord saveWithBlock:] 进行的保存,但大多数情况下,NSManagedObjectContextWillSaveNotification 仅用于后台上下文,FRC 就在那里:

====>> context will save: saveWithBlock:completion: on *** BACKGROUND THREAD ***

在这种情况下,FRC 永远不会收到通知,并且其代表的 controllerWillUpdateContent 永远不会被解雇。

我觉得这可能是一个简单的问题——最好打电话给 Saul! ;) 任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

如果您的保存最终到达默认上下文,那么您的获取结果控制器最终将重新加载最新信息。可能是 ClassicWithBackgroundCoordinatorMagicalRecordStack 未正确设置为通过该堆栈的“上下文”属性进行保存。

【讨论】:

谢谢。如果我在 FRC 上强制执行 MR_perform_fetch(例如,在 viewWillAppear 中),则更改会被拾取,因此更新将进入默认上下文。他们只是没有立即被 FRC 接走。关于我可以尝试什么的任何建议? 我认为我的问题可能是这个(未能更新具有谓词的 NSFetchedResultsController):***.com/questions/3923826/… 答案表明触发 [object willAccessValueForKey:nil] 会有所帮助,但我不清楚是否应该这样做背景上下文(在合并之前)或者如果我需要以某种方式在默认上下文上执行它。感谢您的任何见解。 我想通了(我想)。交易是,当在后台 PSC 中更新值时,需要戳主上下文以查看对象更改。最简单的方法是通过 URI->ObjectID->Object 在主对象存储中查找值,然后在 [MagicalRecord save] 块内对它们运行[willAccessValueForKey:nil]。这可能需要考虑在 MR 中添加支持,因为它似乎是一个常见的用例。【参考方案2】:

我想我明白了。

当在后台 PSC 中更新值时,需要戳主上下文以查看对象更改。最简单的方法是通过 URI->ObjectID->Object 在主对象存储中查找值,然后在 [MagicalRecord save] 块内对它们运行 [willAccessValueForKey:nil]。这样,当更改合并到主上下文中时,他们就会知道自己出错了,即使来自后台 PSC 的更新只是更改。

【讨论】:

还是这样吗?我似乎遇到了一些非常相似的事情,但是调用 [willAccessValueForKey:nil] 不会向我的 FRC 发送更改通知。

以上是关于如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController的主要内容,如果未能解决你的问题,请参考以下文章

MagicalRecord 3.0 设置

MagicalRecord 2.3.0/3.0 在对象内保存对象

MagicalRecord 3.0 不保存。第二次构建没有对象

在并发 NSOperation (MagicalRecord-2.3) 中使用 MagicalRecord 的正确方法

关于MagicalRecord的问题

xcode:如何确保我的二进制文件的部署目标设置为 3.0?