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

时间:2013-12-02 10:00:38

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

主要上下文在主队列中工作,单独的操作在单独的线程和使用私有队列初始化的上下文中工作。一切都很好,但是发生了一个小问题。

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

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

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

MainContext:

- (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;
}

1 个答案:

答案 0 :(得分:2)

  

或许我应该以某种方式告诉后台任务,在FRC完成其工作之前不要删除条目。

这是stinky代码。后台线程不需要知道控制器的用途。

更现代的模式是

- (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会导致奇怪的情况,如果你没有完全正确的话。