5

. _ NSPrivateQueueConcurrencyType_NSMainQueueConcurrencyType

私のコンテキストの初期化:

_managedObjectContext = [[NSManagedObjectContext alloc] 
initWithConcurrencyType:NSPrivateQueueConcurrencyType];  
[_managedObjectContext setPersistentStoreCoordinator:coordinator];

面倒なコード:

NSManagedObjectID *managedObjectID = [self managedObjectIDForEntity:entity 
withParseObjectId:object.objectId];  
managedObject = [context existingObjectWithID:managedObjectID error:error];

バックトレース: バックトレース

Githubプロジェクトにリンクし、Issueにいくつかのコンテキストのイシューを開きます。

4

1 に答える 1

4

あなたは自分の顔を撃った。

executeFetchRequest:error:(親のキューがブロックされている間)何らかの作業を行う別の子コンテキストを作成します。この作業には、( を介してinsertOrUpdateObjects:)親のキューに作業を同期的にディスパッチすることが含まれます。

これはNSManagedObjectContext -existingObjectWithId:、ネストされたコンテキストでは、親のキューにディスパッチして、親コンテキストに失敗したオブジェクトを満たすためです。残念ながらperformBlockAndWait、子コンテキストで親のキューを既にブロックしています。

大きな悲しみが襲います。


編集:可能な解決策についての考え

ここでの問題は、異なるキューを持つネストされたコンテキストの使用によって引き起こされます。提供されたコンテキストが NSMainQueueConcurrencyType でない限り、この状況でネストされたコンテキストを使用する動機を理解しているかどうかはわかりません。

それでも、呼び出しコンテキストのキューからフェッチ作業を強制することは危険です。なぜなら、フェッチ内の既存のオブジェクトは、障害が発生した場合にこの問題の犠牲になるからです (ここで行われているように)。

AFIncrementalStore が何らかの形でこの状況でグラフの分離を保証する可能性があります。AFNetwork に対して提出されたこの問題を見つけました。

https://github.com/AFNetworking/AFIncrementalStore/commit/1f822279e6a7096327ae56a2f65ce8e2ff36da83

保持サイクルがオブジェクトの割り当て解除を妨げ、その結果オブジェクトが親コンテキストに永続的に存在し、失敗しようとしてデッドロックが発生するという点で、疑わしいほど似ています。

于 2014-01-13T07:11:03.627 に答える