-1
@synchronized (self.class)     {
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}

moc 是一个 managedObjectContext

可以是主线程对应的moc。该 moc 是所有 MOC 的父级。

其他 moc 只是孩子。有时当孩子执行executeFetchRequest时,它也会让父moc执行相同的executeFetchRequest。

我经常看到的是

外主线程:

@synchronized (self.class)     {
    fetchedObjects = [moc executeFetchRequest:request error:&error]; //semaphore_wait_trap here
}

在主线程上

@synchronized (self.class)     {//_psynch_mutexwait
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}

好吧...为什么会出现僵局?即使主线程上的 moc 对应于主线程,它根本没有被访问。它在@synchronized 处等待。那为什么要fetchedObjects = [moc executeFetchRequest:request error:&error];等呢?

4

2 回答 2

4

你不应该 @synchronize-ing 调用 executeFetchRequest:

executeFetchRequest:error:方法本质上会根据硬件和工作负载适当地调整其行为。如有必要,Core Data 将创建额外的私有线程以优化获取性能。您不会为此目的创建后台线程来提高绝对获取速度。但是,在后台线程或队列中获取可能仍然是合适的,以防止应用程序的用户界面阻塞。这意味着,如果提取复杂或返回大量数据,您可以将控制权返回给用户并在结果到达时显示结果。

核心数据编程指南:并发

基本上,如果您要返回大量对象并处理它们,最好从私有队列上下文中执行此操作(因为您可以使用该私有队列上的返回对象并从主队列中处理它们)。

如果您有主队列上下文,请仅从主队列中使用它。

此外,子上下文通过将获取请求传递给其父级来执行获取请求。发生的事情(据我所知)是谓词在持久存储(SQL)上以及链中每个 MOC 中未保存的对象上进行评估。这意味着,如果您覆盖谓词中使用的 getter,它将在内存中那些未保存的对象上调用(而 SQL 谓词使用原始 DB 值进行比较)。您可以通过阻止子上下文的队列来死锁父上下文。

于 2013-01-15T15:14:29.413 回答
3

moc 持有自己的锁,所以你有一个锁中的锁 - 现在当 t1 到来时,他获得锁 1 但可能没有锁,因为有人已经在获取并且拥有 lock2 但那个被 t1 阻塞(它正在等待)

于 2013-01-15T10:42:59.483 回答