狠狠撸

狠狠撸Share a Scribd company logo
CoreData 非同期データ処理
永島 次朗 / Jiro Nagashima


Twitter
@hedjirog


nana music, inc. / iOS Engineer
http://nana-music.com
Goal




UI操作を妨害することなく
高度なデータ処理をしたい
Goal
         UI操作を妨害することなく
         高度なデータ処理をしたい



                     解決策



?   CoreDataをマルチスレッドで扱う手法が有効

    ?   複数のContext

    ?   parentContext(iOS5 以上)

    ?   performBlock: メソッド(iOS5 以上)
Agenda

? 颁辞谤别顿补迟补フレームワークの概要
? 颁辞谤别顿补迟补とマルチスレッド
 ? 単一/复数颁辞苍迟别虫迟による设计
 ? CoreDataの便利機能
  ? parentContext(iOS5 以上)
  ? performBlock: メソッド(iOS5 以上)
颁辞谤别顿补迟补フレームワークの概要
Demo
颁辞谤别顿补迟补フレームワークの概要

? 4つのクラスとクラス間の関係
 ManagedObject

 ManagedObject

 ManagedObject

    ManagedObjectContext               PersistentStoreCoordinator




                           FetchedResultsController
颁辞谤别顿补迟补フレームワークの概要


 ManagedObject




? データを表わすオブジェクト
颁辞谤别顿补迟补フレームワークの概要

 ManagedObject

 ManagedObject

 ManagedObject

    ManagedObjectContext




? オブジェクトの集合を管理
? オブジェクトの挿入/更新/削除
颁辞谤别顿补迟补フレームワークの概要

 ManagedObject

 ManagedObject

 ManagedObject                         PersistentStore

    ManagedObjectContext   PersistentStoreCoordinator




? オブジェクトの永続化
? 永続ストアへマッピング
颁辞谤别顿补迟补フレームワークの概要

 ManagedObject

 ManagedObject

 ManagedObject

    ManagedObjectContext               PersistentStoreCoordinator




                                         TableView
                           FetchedResultsController



? オブジェクトの変更を監視
? TableViewの表示と整合性を保つ
颁辞谤别顿补迟补とマルチスレッド
単一Contextによる設計
? 新規オブジェクト追加時
     ManagedObject




        ManagedObjectContext                       PersistentStoreCoordinator




                                                           通知のタイミング
                                                           1. 空のオブジェクト追加時
                               FetchedResultsController    2. オブジェクト更新時
    問題点


?   過剰な通知

    ?   オブジェクトの更新後のみ通知したい
単一Contextによる設計
  ? オブジェクト永続化時
                                 2. 永続化の
       ManagedObject            所要時間が増加



         ManagedObjectContext                       PersistentStoreCoordinator



1. 負荷の高い更新処理



                                FetchedResultsController
      問題点


  ?   永続化に処理時間を要するとUI操作を妨害
単一Contextによる設計

?   過度な通知が発生する可能性

?   永続化時に処理時間を要してUIを妨害する可能性




         複数のContextを作成
复数颁辞苍迟别虫迟による设计
Main Thread


        ManagedObject


          ManagedObjectContext
                                                     PersistentStoreCoordinator




Background

                                 FetchedResultsController
        ManagedObject


          ManagedObjectContext



?   スレッド毎にContextを作成

    ?    メインスレッド:監視対象、永続化向け

    ?    バックグラウンド:(オブジェクトの)更新向け
复数颁辞苍迟别虫迟による设计
     Main Thread


            ManagedObject


              ManagedObjectContext
                                                         PersistentStoreCoordinator

オブジェクト更新後にマージ

     Background

                                                                適切なタイミングで通知
                                     FetchedResultsController
            ManagedObject


              ManagedObjectContext



    ?   適切なタイミングで通知が可能

    ?   Context(スレッド)毎に役割分担

        ?    処理負荷の分散
CoreDataの便利機能


? parentContext(iOS5 以上)
 ? Context間での更新内容のマージが容易に
? performBlock: メソッド(iOS5 以上)
 ? 非同期処理の記述が容易に
parentContext
Main Thread




          ManagedObjectContext

                        親Context                       PersistentStoreCoordinator

        Parent



                        子Context
Background                         FetchedResultsController




          ManagedObjectContext



?   複数のContext間で親子関係を定義できる

    ?    setParentContext: メソッドで親Contextを指定
parentContext
      Main Thread




               ManagedObjectContext

                             親Context                       PersistentStoreCoordinator

             Parent


オブジェクト更新後にマージ
                             子Context
      Background                        FetchedResultsController




               ManagedObjectContext



     ?   Context間での更新内容のマージが容易に

         ?    子Contextのsave: メソッド呼び出しでマージ
parentContext
? 親Contextの作成
  Main Thread




          ManagedObjectContext

                        親Context
                                      Contextの更新処理を行なうスレッドが決定

 NSMangedObjectContext *parentContext;
 parentContext = [[NSManagedObjectContext alloc]
                   initWithConcurrencyType:NSMainQueueConcurrencyType];

 [parentContext setPersistentStoreCoordinator:_persistentStoreCoordinator];
parentContext
? 子Contextの作成
  Main Thread                                    Background
                                   Parent




          ManagedObjectContext                            ManagedObjectContext

                        親Context                                        子Context
                                        Contextの更新処理を行なうスレッドが決定

 NSMangedObjectContext *childContext;
 childContex = [[NSManagedObjectContext alloc]
                initWithConcurrencyType:NSPrivateQueueConcurrencyType];

 [childContext setParentContext:parentContext];

                                            親Contextの指定
performBlock:
?   非同期処理の記述が容易に
 Main Thread                               Background
                                  Parent




         ManagedObjectContext                     ManagedObjectContext

                       親Context                                 子Context

[childContext performBlock:^{       非同期で処理が実行される
    // push to parent
    NSError *error;
    if (![childContext save:&error]) {
        // handle error
    }
?
    [parentContext performBlock:^{        非同期で処理が実行される
        NSError *error;
        if (![parentContext save:&error]) {
            // handle error
        }
    }];
}];
performBlock:
?   parentContextとの組み合わせ
 Main Thread                                   Background
                                  Parent




         ManagedObjectContext                         ManagedObjectContext

                       親Context                                     子Context

[childContext performBlock:^{
    // push to parent
    NSError *error;
    if (![childContext save:&error]) {
        // handle error
    }
                                              親Contextへ変更内容をマージ
?
    [parentContext performBlock:^{
        NSError *error;
        if (![parentContext save:&error]) {
            // handle error
        }
    }];
}];
performBlock:
?   parentContextとの組み合わせ
 Main Thread                                  Background
                                  Parent




         ManagedObjectContext                        ManagedObjectContext

                       親Context                                    子Context

[childContext performBlock:^{
    // push to parent
    NSError *error;
    if (![childContext save:&error]) {
        // handle error
    }
?
    [parentContext performBlock:^{
        NSError *error;
        if (![parentContext save:&error]) {
            // handle error
        }
                                              親Contextの永続化
    }];
}];
まとめ

? UI操作を妨害しない高度なデータ処理
? CoreDataをマルチスレッドで利用する
 ? 複数のContextを用意
 ? parentContext で親子関係を定義
 ? performBlock: メソッドで非同期処理
参考資料


? Multi-Context CoreData
 http://www.cocoanetics.com/2012/07/multi-context-coredata/
より詳しい情報


?   WWDC 2011
    ?   Session 303 - What's New in Core Data on iOS

    ?   Session 315 - What's New in Core Data on Mac OS X


?   WWDC 2012
    ?   Session 214 - Core Data Best Practices

More Related Content

CoreData 非同期データ処理