Objective c 核心数据保存但不保存-专用队列跳转线程
我尝试在后台运行同步引擎,并使用Objective c 核心数据保存但不保存-专用队列跳转线程,objective-c,multithreading,core-data,grand-central-dispatch,Objective C,Multithreading,Core Data,Grand Central Dispatch,我尝试在后台运行同步引擎,并使用NSPrivateQueueConcurrencyType如下所示: - (NSManagedObjectContext *)workerContext { NSManagedObjectContext* workerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; workerContext.
NSPrivateQueueConcurrencyType
如下所示:
- (NSManagedObjectContext *)workerContext
{
NSManagedObjectContext* workerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
workerContext.parentContext = self.mainContext;
return workerContext;
}
我想我需要一个专用的后台队列,所以我也创建了这个:
- (dispatch_queue_t)syncQueue {
if (!_syncQueue) {
_syncQueue = dispatch_queue_create("com.me.syncEngineSyncQueue", 0);
}
return _syncQueue;
}
我遇到了一个问题,NSManagedObject删除正在发生,但是,它被逆转了。我目前的猜测是,它与线程有关
我在同步引擎中记录了断点,并注意到相同的syncQueue
在不同的时间在不同的线程上运行。这可能是我的问题吗
如果是这样,我如何创建在一个线程上一致运行的调度队列
我想我需要一个专用的后台队列,所以我创建了这个
以及:
Bzzzzt。错。核心数据为您解决这一问题。当您使用NSPrivateQueueConcurrencyType
初始化MOC时,它附带了自己的内部管理GCD队列。你一点也不介意
但是,必须通过NSManagedObjectContext
的performBlock
API完成与该MOC相关的任何工作。除其他外,该API基本上将块放在特殊的专用GCD队列上,并安排它执行
如果是这样,我如何创建一个调度队列,该队列在一台计算机上一致运行
线
你没有。这就是GCD的魅力所在。您将代码块插入到消息队列中,然后“某些”线程将它们从消息队列中剥离出来并执行它们。您可能不太关心哪个线程正在这样做(除了主队列)
编辑
明白了。但是,我仍然需要保存mainContext,它是 我的workerContext的父母,对吗?我需要打电话给银行吗 主线?现在我正在执行[self.mainContext save:&error];在里面 使用保存workerContext后的主线程 performBlockAndWait–Ramsel 5小时前 您最好将每个上下文视为其自身的实体,并且在与需要在主线程上进行交互的UI元素交互时,只“利用”知道主上下文在主线程上运行 如果要在保存子上下文后保存父上下文,请执行类似操作,这是
NSManagedObjectContext
上的一种可能的分类方法
- (void)_saveRecursively:(BOOL)recursiveSave
withCompletion:(void(^)(NSError *error))completion {
NSError *error;
if ([self save:&error]) {
error = nil;
NSManagedObjectContext *parent = self.parentContext;
if (parent != nil && recursiveSave) {
return [parent performBlock:^{
[parent _saveRecursively:recursiveSave withCompletion:completion];
}];
}
}
completion(error);
}
上述方法是“私有”的,不应公开。它保存当前上下文。如果要求执行递归保存,它将继续保存层次结构,直到它结束,或者直到其中一个保存操作失败
然后,它将调用完成处理程序,如果失败,则传递NSError
的实例,如果成功,则传递nil
的实例
- (void)saveRecursively:(BOOL)recursiveSave
withCompletion:(void(^)(NSManagedObjectContext *moc, NSError *error))completion {
[self _saveRecursively:recursiveSave withCompletion:^(NSError *error) {
if (completion) {
[self performBlock:^{
completion(self, error);
}];
}
}];
}
此方法为用户提供类别API。它确保在原始保存上下文的受保护范围内异步调用完成块。这样,您可以保证完成块可以安全使用,而不必调用另一个performBlock
- (void)saveWithCompletion:(void(^)(NSManagedObjectContext *moc, NSError *error))completion {
[self saveRecursively:YES withCompletion:completion];
}
这为异步保存整个层次结构提供了一种方便的方法
这意味着您可以像这样调用save方法
[childContext saveWithCompletion:^(NSManagedObjectContext *moc, NSError *error) {
// moc will be the same as childContext, and you can use the variable moc
// safely, knowing this block is running in its own performBlock
if (error) {
// Handle the save error
} else {
// Handle the successful save
}
}];
明白了。但是,我仍然需要保存
mainContext
,它是我的workerContext
的父级,对吗?我需要在主线程中调用save吗?现在我正在执行[self.mainContext save:&error]使用performBlockAndWait保存workerContext
后,在主线程中执行code>