バックグラウンドスレッドが所有する新しく作成されたNSManagedObjectContextを介して、バックグラウンドスレッドで(GCDを使用して)高価なフェッチ(約5秒、約30,000オブジェクト)を実行しています。
ただし、メインスレッドが永続ストアのロックを待機しているため、UIがフリーズするため、これをバックグラウンドで実行するメリットは得られません。スタックトレースは次のとおりです。
* thread #1: tid = 0x1c03, 0x3641be78 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore], stop reason = breakpoint 1.1
frame #0: 0x3641be78 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore]
frame #1: 0x36432f06 CoreData`-[_PFManagedObjectReferenceQueue _processReferenceQueue:] + 1754
frame #2: 0x36435fd6 CoreData`_performRunLoopAction + 202
frame #3: 0x35ab9b1a CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 18
frame #4: 0x35ab7d56 CoreFoundation`__CFRunLoopDoObservers + 258
frame #5: 0x35ab80b0 CoreFoundation`__CFRunLoopRun + 760
frame #6: 0x35a3b4a4 CoreFoundation`CFRunLoopRunSpecific + 300
frame #7: 0x35a3b36c CoreFoundation`CFRunLoopRunInMode + 104
frame #8: 0x376d7438 GraphicsServices`GSEventRunModal + 136
frame #9: 0x33547cd4 UIKit`UIApplicationMain + 1080
frame #10: 0x000f337a MyApp`main + 90 at main.m:16
私は(信じています)このバックグラウンドスレッドが作業を行っている間、メインスレッドのNSManagedObjectContextにアクセスしていないことを確認しました。そして、スタックトレースから、私がCoreDataで直接何もしていないことは明らかです。しかし、何かが_processReferenceQueueの呼び出しをトリガーしました。これにより、ストアをロックしようとします。誰かがこのメソッドが何をするのか、そして私のバックグラウンドスレッドがその仕事をしている間にそれが呼び出されるのをどのように/防ぐことができるかを知っていますか?
編集
このバックグラウンドフェッチを開始した後、メインスレッドでCoreDataの読み取りまたは書き込みを行っていません。だからこれはとても不可解です。メインスレッドもさらに作業を行おうとすると、競合が発生することが予想されますが、そうではありません。少なくとも、私はそれを要求していません。読み取り、書き込み、FRCはありません。そのため、この_processReferenceQueueメソッドに精通している人がいるかどうかを知りたいと思います。なぜ呼ばれるのですか?何が原因で実行されているのでしょうか。
編集
テストとして、MTのMOCを保留中の変更がない状態にしてから、BTをオフにしてフェッチを実行しようとしました。_processReferenceQueue
これは、ロックが必要な作業を行う必要がないことを期待しています。店で。
BTを開始する前に、[MOC updatedObjects]
セットに1つのオブジェクトがあることに気づきました。挿入または削除されたセットにオブジェクトはありませんでした。
を呼び出した後、予想どおり[MOC save]
、[MOC updatedObjects]
セットは空でした。しかし、私がBTを開始した後も、MOCに汚れがないはずなのに
、MTはまだ店内をロックしようとしました。_processReferenceQueue
私が(厳密にテストとして)次に試したMOC reset]
のは、BTを開始する前に代わりに[を呼び出すことでした。[MOC updatedObjects]
予想通り、リセット後もセットは空でした。コードのこの時点では、BTが作業を終了するまで、MT上の管理対象オブジェクトに触れていません(したがって、既に参照している管理対象オブジェクトを無効にするリセットが原因で問題が発生することはありません)。ただし、今回は、MTはで永続ストアをロックしようとしません_processReferenceQueue
でした。
この動作は、BTを開始した後、MTのMOCで明示的なことを何もしていないことを示しています。そうしないと、MTは、の内部または外部のある時点(読み取りまたは書き込み用)でロックを要求することになります_processReferenceQueue
。しかし、そうではありませんでした。
最近保存されたMOCが後続のロックインを必要とするの_processReferenceQueue
に対し、最近リセットされたMOCが必要としない理由はわかりません。
掘り続けます。
ありがとう!ブライアン