3

ユーザーが明示的に [同期] ボタンを押した後、潜在的に大量のデータを Web からインポートし、Core Data を使用してそのデータを保存するアプリがあります。フィードバックを表示したいのですが、これが発生している間、ユーザーがアプリの残りの部分を操作したくないので、[同期] ボタンを押すと、モーダル ダイアログが表示されます。操作をすぐに実行したいので、操作は viewDidAppear メソッドで実行されます。私はこれが眉をひそめていると確信しています。

現在、このアプローチには多くの問題があります。

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

私はこれに関する Apple のドキュメントを読んでいますが、この特定のニーズの組み合わせに関するより簡潔なガイダンスを見つけることを期待して、これを尋ねています。ありがとう。

4

1 に答える 1

2

メインスレッドをフリーズしないでください。特定の UI アクションを「禁止」することもできます。

子として別のコンテキストを作成し、そこですべての作業を行います。完了したら (または特定の間隔で)、コンテキストをメイン コンテキストに保存し、メイン スレッドに 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...
    }];
}];

注意すべき点がいくつかあります... mainMOC は、プライベートまたはメイン キューの同時実行タイプである必要があります。アプリ デリゲートにある Core Data テンプレートを使用している場合は、alloc/init を initWithConcurrencyType:NSMainQueueConcurrencyType に変更するだけです。

ただし、正規のメイン/親の関係を使用することをお勧めします。プライベート MOC を作成し、それを永続ストアに割り当ててから、メイン MOC を作成し、その親をそのプライベート MOC に設定します。これで、UI をブロックすることなく、バックグラウンド操作で I/O を処理する準備が整いました。

それでも、Web からロードする場合は、上記のパターンを使用します: 子 MOC を作成してから、オブジェクトをメイン MOC にロードします。

「ルート」MOC 呼び出しが保存されるまで、データはディスクに保存されないことに注意してください。

于 2012-05-08T15:40:25.707 に答える