CoreData
非同期処理
Swift

Swift4を使ったCoreDataマルチスレッド非同期対応

iOS開発でCoreDataのマルチスレッド対応していました。
CoreDataを使って

  • 保存されていない
  • 保存より先にreturn処理が走る

と問題が発生し、また下記の使い方を見直す。

  • privateQueueConcurrencyType
  • mainQueueConcurrencyType

この際に参考した本は、
https://smtebooks.com/book/5567/core-data-tutorials-ios-10-swift-3rd-edition-pdf
です!

1. 親子関係を作る

class DataController: NSObject   {
//親Context作成は下記のようにする
static var parentContext: NSManagedObjectContext = {
        return NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) // privateの設定
    }()

//子Context作成は下記のようにする
func subManagedObjectContextMake() -> NSManagedObjectContext {
        let subContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)//mainの設定
        subContext.parent = DataController.managedObjectContext//親設定
        return subContext
    }

//その他必要なもの
}

2.変更処理例

追加/変更のみ

  1. let context = DataController.subManagedObjectContextMake()で、subContextを作る
  2. context内容を変更する
  3. subContextを更新する
  4. parentContextを更新する
// 3.subContextを更新対応
例)
context.perform {
     do {
         try context.save()
         DataController.saveParentContext()//parentContext保存処理
    } catch {
         fatalError("Failure to save context: \(error)")
    }
}

// 4.subContextを更新対応
例)
func saveParentContext() {
     DataController.parentContext.perform {
          do {
              try DataController.parentContext.save()
         } catch {
              fatalError("Failure to save context: \(error)")
         }
     }
}

これにより安定してデータ更新が実現できました。

表示対応

parentContextでしないと、最新の情報が取得できないため
1. let context = DataController.parentContextでparentContextをセットする
2. context内容から情報を取得する

削除対応

parentContextでしないと、削除が反省されないため
1. let context = DataController.parentContextでparentContextをセットする
2. context内容からレコードをdeleteする
3. parentContextを保存する

まとめ

ここまで何度もリリースしながら様子を見てきました。
最後なんとか止まり、うまく動くようになってよかったです。
本の力は、偉大だなと感じた今日この頃でした。
何か間違え等があったら、教えてください。
ご一読していただき、ありがとうございました。