我一直在试验马库斯·扎拉的核心数据书推荐的核心数据设置。设置包含两个托管对象上下文。具有并发类型私有的父moc。和儿童的主要背景。这背后的理由是,主核心数据上下文可以具有超级快读/写,因为主上下文的更改(在主队列上)被传播到父服务器,而不是磁盘。
然而,Zarra的核心数据初始化方法在同一个线程上设置每个上下文。因为执行器*方法是在创建managedobjectcontext的同一个队列上执行的,所以听起来所有核心数据的读/写都将发生在主队列上。在后台线程上设置私有上下文不是更好吗?
这种想法促使我编写了代码(受Zarra书中的代码启发),类似于以下内容:
__block NSManagedObjectContext *private = nil;
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSPersistentStoreCoordinator *psc = nil;
psc = [self persistentStoreCoordinator];
NSUInteger type = NSPrivateQueueConcurrencyType;
private = [[NSManagedObjectContext alloc] initWithConcurrencyType:type];
[private setPersistentStoreCoordinator:psc];
});
NSManagedObjectContext *moc = nil;
type = NSMainQueueConcurrencyType;
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:type];
[moc setParentContext:private];
_mainManagedObjectContext = moc;
_backgroundObjectContext = private;
...
当我像这样设置我的核心数据堆栈时,最后会出现来自performBlockAndWait的死锁,因为主线程等待自己释放,以便执行work...ad无穷大块。奇怪的是,我试图执行的队列不仅仅是任何全局队列--它是主线程。出于某种原因,具有内置全局队列之一的dispatch_sync (或我自己创建的dispatch_queue )并不保证用于所选工作块的线程将是主线程以外的线程。除了gcd之外,还有其他的方法(例如使用ns线程等.)以确保块将在主线程以外的线程上执行。
发布于 2014-08-12 04:26:13
因为执行器*方法是在创建managedobjectcontext的同一个队列上执行的,
这种说法完全是错误的。
使用performBlock
的唯一方法是使用私有队列或主队列,而对performBlock
的每次调用都将在适当的队列上对块进行排队,而不管在创建MOC时涉及哪个线程/队列。
现在,您的死锁是由于使用了与performBlockAndWait
不同的行为而导致的。performBlockAndWait
将导致调用线程等待,直到块可以针对MOCs调度队列同步执行。
而且,也不能保证在哪个线程上运行某些代码块.除了“主”队列的情况外。
最后,我们应该很少使用,如果使用performBlockAndWait
的话。是的,它是重新进入的,但它也会导致死锁。应该只在特定情况下使用它,因为您肯定知道被调用的代码不可能从任何其他块调用。如果您的代码是异步的,这应该是非常罕见的。
发布于 2014-08-11 16:03:45
您似乎对所使用的哪个分派功能感到困惑。在您的代码中,它是"_sync",但在散文中是"_async“。dispatch_sync的目的是阻止当前线程,直到某些事情完成为止,因此这将被期望为您如何编写它。试一试dispatch_async。
https://stackoverflow.com/questions/25254125
复制相似问题