文档声明带有NSPrivateQueueConcurrencyType的NSManagedObjectContext允许用户使用performBlock:执行异步代码。但是,如果我想编写一个NSOperation子类来处理这种子上下文/私有队列设置中的托管对象,会发生什么?
例如:
// Get managed object IDs from selected objects (defined in one of my own categories).
NSArray * selectedObjIDs = [NSManagedObjectContext IDsWithObjects:self.arrayController.selectedObjects];
NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:^
{
NSManagedObjectContext * childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = myMainMOC;
[childContext performBlock:^
{
// Get objects in child context with previously generated managed object IDs (again, from my own category).
NSArray * privateObjects = [childContext objectsWithIDs:selectedObjIDs];
// Do something with the objects.
for( NSManagedObject * object in privateObjects )
{
[object setValue:@"New Title" forKey:@"title"];
}
[childContext save:NULL];
}];
}];
// Execute in our own private NSOperationQueue.
[self.backgroundQueue addOperation:operation];
代码工作正常,但在两个块中设置断点时,我可以看到执行首先进入后台线程A(由NSBlockOperation生成),然后进入后台线程B(专用于子MOC - 正如预期的那样。
(顺便说一句:我相信我在Apple的WWDC会话“高级NSOperations”的示例代码中看到了相同的设置。)
问题#1:这两个嵌套的调度是否存在某种问题,即在性能方面?它对我来说似乎不对 - 代码不应该只在子MOC的私有队列中运行吗?
问题#2:想象一下我会继承NSOperation(而不是使用NSBlockOperation)。我是否应该覆盖其“异步”属性以向返回YES 只使用子MOC的私有队列?
答案 0 :(得分:0)
你的代码并不完全错误,但它比它需要的更复杂。
当您调用performBlock
时,您告诉托管对象上下文在专用队列上异步执行该块。对于调用performBlock
的代码,该块已经是异步的。将其包裹在NSOperation
中可能是安全的,但也完全没有必要。代码调用performBlock
后,NSOperation
将完成,因为performBlock
的异步性质。简而言之,NSOperation
在这里完全没必要。
您可以将performBlock
替换为performBlockAndWait
,但这没有多大意义。你强迫NSOperation
等待,但没有充分的理由。
除非您有其他一些未提及的异步要求,否则您提及的子类NSOperation
也是不必要的。如何配置NSOperation
无关紧要 - 只需摆脱它。
更新,因为在评论中您似乎执行还有其他异步要求......
performBlock
立即返回,队列中的下一个操作将与另一个队列并行运行。那有关系吗?这取决于队列中的其他操作正在做什么。如果他们依赖这个performBlock
已完成,那就是一个问题。您可以使用performBlockAndWait
来处理此问题,以使队列保持连续。