【Swift UI】Core Dataをマルチスレッドで扱う際の注意点!Managed Object Context

この記事からわかること

  • Swift UICore Data利用する方法
  • マルチスレッドでの使い方
  • Managed Object Context(MOC)の役割定義方法
  • -com.apple.CoreData.ConcurrencyDebug 1とは?
  • アプリクラッシュ(EXC_BAD_ACCESS)する際の原因解決方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Core Dataはスレッドセーフではない?

公式リファレンス:

Core Dataでローカルにデータを保存する機能を利用する際にはコンテキスト(Managed Object Context)を使用します。このManaged Object Contextがスレッドセーフではないため、データの参照や追加などを扱う際に複数のスレッドやバックグラウンドスレッドから操作するとアプリがクラッシュする可能性があります。

解決方法としては「スレッドごとにManaged Object Contextを作成しスレッドごとのNSPersistentContainerを作成する」方法が公式で推奨されています。クラッシュを解決したいだけで、パフォーマンスに影響がなさそうならスレッドを統一するのも1つの手かもしれません。

バックグラウンド用のコンテキストはnewBackgroundContextメソッドから取得できるようです。

private static var contextBackground: NSManagedObjectContext {
    PersistenceController.shared.container.newBackgroundContext()
}

またperformメソッドを使用してバックグラウンドスレッド上で処理を行わせることもできるようです。

let context = persistentContainer.viewContext
context.perform {
    // バックグラウンドスレッドで実行される処理
}

スレッドセーフとは?

スレッドセーフとはマルチスレッドが有効でな実行環境で、特定の処理を複数のスレッドで並行して実行しても、問題が生じない仕様や設計になっていることを指します。SwiftではGCD(Grand Central Dispatch)と呼ばれるマルチスレッド処理を行うための機能が提供されています。

マルチスレッドになっていないかチェックする方法

Core Dataを導入しているプロジェクトでマルチスレッドでコンテキストが利用されているかをチェックするためにはXcodeのスキームの引数に-com.apple.CoreData.ConcurrencyDebug 1を追加して有効にした状態でビルドします。

【Swift UI】Core Dataをマルチスレッドで扱う際の注意点!Managed Object Context

アプリを操作すると異なるスレッドでContextが参照された際にEXC_BREAKPOINTなどのエラーが発生して教えてくれるようになりました。

マルチスレッドで実行すると発生するエラー

マルチスレッドでコンテキストが利用されている場合に必ずエラーが発生するわけではないようで、正常に動作する場合やアプリがクラッシュする場合など状況に応じて変化するようです。

クラッシュはしないがXcodeのログに以下のようなエラーが表示されたり

CoreData: error: NULL _cd_rawData but the object is not being turned into a fault

以下のエラーが発生しアプリがクラッシュすることもありました。

EXC_BAD_ACCESS (code=1, address=0xb91088020)

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index