objective-c - NSFetchedResultsController,后台线程中的多线程和删除

标签 objective-c cocoa-touch cocoa core-data nsfetchedresultscontroller

主上下文在主队列中工作,单独的操作在单独的线程中工作,并且上下文使用私有(private)队列初始化。一切都按预期工作得很好,但发生了一个小问题。

我发现有时当我从后台线程删除记录时,我会遇到有关访问 FRC 内的故障对象的异常。看来当FRC处理它得到的条目并且后台线程删除相同的对象时,就会发生这种情况。

我应该怎样做才能防止异常发生?我看到的一种解决方案是在托管对象上使用特殊属性来指示它(对象)已被删除。或者也许我应该以某种方式告诉后台任务在 FRC 完成工作之前不要删除条目。

已编辑:我的代码订阅了 NSManagedObjectContextDidSaveNotification。目标SDK:iOS 7

主上下文:

- (NSManagedObjectContext *)mainManagedObjectContext
{
if (_mainManagedObjectContext != nil) {
    return _mainManagedObjectContext;
}

_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainManagedObjectContext.persistentStoreCoordinator = [self persistentStoreCoordinator];
return _mainManagedObjectContext;
}

背景上下文:

- (NSManagedObjectContext*)newPrivateContext
{
    NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    context.persistentStoreCoordinator = self.persistentStoreCoordinator;
    return context;
}

最佳答案

Or maybe I should somehow tell the background task not no delete entries until FRC finishes its work.

那就是 stinky代码。后台线程不需要知道 Controller 在做什么。

更现代的模式是

- (NSManagedObjectContext*)newPrivateContext
{
    NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    context.parent = self.mainManagedObjectContext;
    return context;
}

然后...

NSManagedObjectContext *workerContext = [self newPrivateContext];

[workerContext performBlock:^{

    //stuff to be done on the background thread

    NSError *error = NULL;
    if ([context save:&error]) {
        //handle error
    }

}];

这项工作将在后台线程上完成,您可以删除对 NSManagedObjectContextDidSaveNotification 的观察,因为在两个上下文之间建立父子关系会自动处理该关系。

不确定这是否是您问题的全部,但如果您做得不正确,使用NSManagedObjectContextDidSaveNotification可能会导致奇怪的情况。

关于objective-c - NSFetchedResultsController,后台线程中的多线程和删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20325449/

相关文章:

macos - 创建看起来像按钮的工具栏项

macos - 您必须拥有有效的 Mac 应用程序证书才能创建配置文件

objective-c - 如果标签包含 NSAttributed 字符串且部分字符串为粗体,如何获取标签的准确高度

iphone - Iphone 6.0 模拟器视网膜显示屏 4.0 英寸顶部和底部有空白

ios - 使用缓存的 UIView 设置 tableView 中的单元格背景 View :willDisplayCell:forRowAtIndexPath:

objective-c - 将 NSData 字节转换为 NSString?

ios - 在 objective-c 中生成初始化向量

ios - 有什么方法可以从 iOS 应用程序对卡进行收费,而无需从我们的服务器进行后端收费。(Stripe - iOS)

objective-c - Objective-C : How to add color to entire cell (with a disclosure indicator)

objective-c - iOS 上的 DropBox 应用程序是否有 URL 架构?