2012-05-03 17 views
3

私は、ユーザーが明示的にSyncボタンを押した後、ウェブから潜在的に大量のデータをインポートし、コアデータを使用してそのデータを保存するアプリを持っています。私はフィードバックを表示したいので、この間にユーザーが他のアプリケーションとやりとりすることを望まないので、同期ボタンを押すとモーダルダイアログが表示されます。操作がすぐに実行されるようにするため、操作はviewDidAppearメソッドで実行されます。私はこれがぶち壊されていると確信しています。コアデータを使用する長期実行フォアグラウンド操作のベストプラクティス?

は今、アプローチでの問題の束があります。

  • すべてがメインスレッドで行われます。アクティビティインジケータにはアニメーションが継続されるため、ユーザーの種類のフィードバックが得られますが、進行状況を示す方法や中間メッセージを表示する方法はありません。これは正しいことではありません。
    • コアデータを使用する場合、すべてがメインスレッドを使用する必要があるため、別のスレッドに作業を分割することは簡単ではないようです。
  • アプリがバックグラウンドの状態(ユーザーがホームボタンを押すかiPadがスリープ状態になる)に入ると、ゲームが終了して操作が終了する。これがなぜそうであるのかは、ドキュメントからわかります。
    • 「私はバックグラウンドに入っています」というイベントがありますが、ファイルのダウンロード中にコードの実行を別の場所に移すことはできません。私が使用しているソリューションは、バックグラウンドへのトランジションの前後に同じように実行される連続的なアクションでなければなりません。
    • 私は操作がフォアグラウンドで実行されることをユーザーが望む限りは望みます。この操作が行われている間、アプリの他の部分とやり取りすることは意味がありません。

私はこの上で、アップルのマニュアルを読んでいますが、私はニーズのこの特定の組み合わせにより簡潔なガイダンスを見つけることを期待してこれを求めています。ありがとう。

+0

メインスレッドを必要とするコアデータについての記述は真ではありません。同時実行性のセクションをご覧ください:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html –

+0

@T Reddyそうです。私のステートメントは、メインスレッドのマネージオブジェクトコンテキストをワーカースレッドに渡そうとする場合にのみ当てはまります。ワーカースレッドで新しい管理対象オブジェクトコンテキストを作成すると、それがサポートされます(主スレッドの管理オブジェクトコンテキストで作業者のコンテキストが変更されたことを認識させるために何かをする必要があります)。 –

+0

コンテキストだけでなく、管理対象オブジェクトがスレッド境界を越えることはできません。私はこのマネージオブジェクトラッパーを使用して、Core Dataのドキュメントに記載されているスレッド要件を容易にしました。https://github.com/chriscdn/RHManagedObject –

答えて

2

本当にメインスレッドをフリーズするべきではありません。特定のUIアクションを「禁止する」ことはできます。

子として別のコンテキストを作成し、そこですべての作業を行います。物事のカップル

NSManagedContext *backgroundContext = [NSManagedContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
backgroudContext.parentContext = [self mainManagedObjectContext]; 
[backgroundContext performBlock:^{ 
    // This block is running in a background thread. 
    // Go get your data from the web 

    // Call this to push data to the main MOC (either at end, or at intervals) 
    [backgroundContext save:&error]; 

    // When you want to do something on the main thread... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // This block is running on the main queue... I can do anything with the UI... 
    }]; 
}]; 

...完了(または一定の間隔で)、メインコンテキストにコンテキストを保存し、いくつかのUIの更新対話...多分プログレスバーや何かをするメインスレッドに通知した場合あなたのmainMOCはプライベートまたはメインキューの同時実行型である必要があります。コアデータテンプレートを使用している場合は、アプリケーションデリゲートにある場所で、alloc/initをinitWithConcurrencyType:NSMainQueueConcurrencyTypeに変更します。

ただし、標準的なメイン/ペアレント関係を使用することをお勧めします。プライベートMOCを作成し、それを永続ストアに割り当て、次にメインMOCを作成し、その親をそのプライベートMOCに設定します。これで、UIをブロックすることなく、バックグラウンド操作でI/Oを処理できるようになりました。

ウェブから読み込むときは、上のパターンを使用します。子MOCを作成し、主MOCにオブジェクトを読み込みます。

"ルート" MOC呼び出しが保存されるまで、データはディスクに保存されません。

関連する問題