2017-08-21 8 views
0

コアデータの並行性の問題のデバッグに問題があります。私の方式ではコアデータプライベートコンテキストperformAndWaitにより、デバッグがクラッシュする

は私が有効になって:

-com.apple.CoreData.Logging.stderr 1 
-com.apple.CoreData.ConcurrencyDebug 1 

私は、バックグラウンドスレッドでコアデータからレコードをフェッチしたいと思います。

私のUIViewControllerでは、DispatchQueue.global(qos: .background).asyncを作成します。ここでは、Core Dataを呼び出してレコードを取得します。

私は、親/子を使用しています:

func performStationsFetch(filter: String = "") -> [Stations] { 
    let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) 
    let parentMOC = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext 

    privateMOC.parent = parentMOC 

    var fetchResults: [Stations] = [] 

    privateMOC.performAndWait { 
     let fetchRequest: NSFetchRequest<Stations> = Stations.fetchRequest() 
     fetchRequest.predicate = NSPredicate(format: "name contains[c] %@", filter) 

     do { 
      fetchResults = try privateMOC.fetch(fetchRequest) 
     } catch { 
      print("Fetch error") 
     } 
    } 

    return fetchResults 
} 

問題は、私はprivateMOC.performを呼び出す場合、コードは正常に動作しています。

しかし、私は、コードがクラッシュprivateMOC.performAndWaitを呼び出し、私に+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]

を与えた場合、誰が問題になることができるかの提案を持っていますか?

答えて

1

マルチスレッド違反は、関数の結果にアクセスしようとすると発生します。 performを使用した場合、結果は空です。問題はありません。 performAndWaitを使用すると、間違ったスレッドでほぼ確実にアクセスされているmanagedObjectsが返されます。

これらのオブジェクトを使用しようとすると、悪意のあるアクセスエラーが発生することがあります。 ManagedObjectsは通常のNSObjectと似ていません。 managedObjectは単なるobjectIdであり、コンテキストへのポインタです。そのプロパティにアクセスする必要があるときはいつでも、要求をコンテキストに転送する必要があります。したがって、そのコンテキストが削除されると、それらのオブジェクトは機能しません。コードでは、関数が終了すると、結果を裏付けるコンテキストがメモリから削除されます。 (注:コンテキストがすぐに削除されるとは限りません。 デバッグ環境では、コンテキストは少しだけ保持されます。本番では、関数の最後にすぐに解放されます)。

したがって、関数の結果にアクセスすることは、2つの理由から不正です.1)スレッドが間違っていて、2)バッキングコンテキストがありません。

いくつかの解決策があります。 1つは、必要な値をmanagedObjectからコピーし、配列または文字列、またはカスタムオブジェクト(NSObjectサブクラス)を返すことです。

もう1つの解決策は、アプリケーションの有効期間中のメインコンテキストでフェッチを行うことです。

代わりに、使用するコンテキストを関数に渡すことができます。また、呼び出し側は、managedObjectsが必要な間、コンテキストが保持されるようにするのは責任があります。

+0

答えを更新したので、コード全体が表示されるようになりました。あなたが提供したリンクを勉強します。 – Matic1911

+0

ご協力いただきありがとうございます。私はあなたの努力に感謝します。 – Matic1911

関連する問題