5

アプリのデータベースは、数層の深さでネストされたオブジェクトで構成されています。アーキテクチャ上の理由から、現時点でこれを移行することは現実的ではありません。

毎日、かなりの割合のデータが期限切れになります。データベースのサイズが大きくなると、アプリのパフォーマンスが低下します。

したがって、データベースを小さく保つ効果的な方法を見つける必要があり (少なくともこのリリースでは)、次のいずれかの方法を検討しています。

  1. applicationWillResignActive の間、ルート レベルですべてのオブジェクトを反復処理し、それぞれに対して delete を呼び出し、削除を「to-many」オブジェクトの 3 つのレイヤーにカスケードできるようにすることで、NSManagedObjects を削除します。これには、最後に 1 つのコンテキストを保存して、すべてを DB にコミットすることが含まれます。多くの場合、オブジェクトの削除には 10 ~ 20 秒 (iPhone 4 の場合) かかり、Springboard は 10 秒でプロセスを終了します。これの主な欠点の 1 つは、コンテキストの保存が 10 秒のタイムアウトまでに完了しない場合、何も削除されず、ユーザーがアプリを実行するたびに DB が拡大し続けることです。

  2. didFinishLaunchingWithOptions または applicationDidBecomeActive 内、または applicationWillResignActive 内の sqlite ファイル全体を削除します。これにより、削除されたデータを表示しようとするのを避けるために、アプリのビュー コントローラー スタックのルートにポップすることが強制されます。これの最大の欠点は、ユーザーが次にアプリを起動したときに何かを実行できるようになるまでに、アプリが数秒間データをダウンロードして解析する必要があることです。

  3. ユーザーがホームボタンまたは電源ボタンを押した後、beginBackgroundTaskWithExpirationHandler を使用して DB オブジェクトを削除します。これに関連して、それを怖がらせる未知数があります。誰かがこの方法で(成功して)やっていますか?

  4. アプリの実行中に、オブジェクトの小さなグループを段階的に削除します。これにより、デバイスの負荷が増加し、テーブルビューの滑らかさが損なわれ、ぎくしゃくします。古いオブジェクトの削除と同時に API 呼び出しによって既に解析されているデータの量は、ここでは実用的ではないようです。

コア データ内のオブジェクトを削除するためのベスト プラクティスについての考えをいただければ幸いです。

4

3 に答える 3

1

データを消去する時間がないという状況に遭遇しました。

いくつかの重要なエンティティを削除済み (エンティティ属性) としてマークし、後で実際にそれらを削除 (およびカスケード) する問題を解決しました。削除されたすべてのエンティティをマークする必要はありません。延期された削除を許可する意味のあるものだけをマークする必要があるため、UI は、マークされているかどうかに関係なく、エンティティが削除されようとしているかどうかを簡単に知ることができます。難しそうに聞こえますが、データ モデルが十分にきれいであれば、難しいことではありません。

アプリの再起動時に、エンティティを削除してカスケードします-これが最後に行けない場合は、可能であれば削除を再開します-または、最初に反復してすべての削除可能なエンティティをマークし、場合によってはそれらを「1つずつ削除します」 "。これは、UI を台無しにすることなくバックグラウンドで実行できます (UI は削除可能なエンティティを認識しているため)。そうすることでパフォーマンスの問題が発生した場合は、削除を段階的に簡単に処理できます。

その「後でマークして削除する」というポリシーは、私にとってはうまく機能しました。

于 2012-07-24T11:51:21.833 に答える
1

オレンジ80、

-applicationDidEnterBackground: 内から起動されたバックグラウンド キューでカスケード削除を実行する必要があります。終了しないようにするには、バックグラウンド タスク ID を使用する必要があります。

私はこの戦略を、頻繁にチャーンするインスタンス CD アプリで使用しています。概して、この戦略を使用すると、ユーザーには削除が表示されません。

アンドリュー

于 2012-07-24T17:04:04.903 に答える
0

You may want to consider doing option 1 in combination with flagging certain entities for deletion. That way even if the delete does not complete upon app exit, upon startup (assuming your app launch doesn't already take some time) you can perform deletions of the flagged entities (for say a couple seconds) and then resort to doing "light" deletes in the background, say when there is no user interaction (no moving table view). Sure, this will add some time to firing up the app, but I think it may be a viable option given your circumstances.

Additionally, I hope that you are performing batch loads via Core Data and are only loading objects into memory as needed.

Quickly rereading your question I just had another thought... Along the lines of #2... why don't you experiment with migrating your obsolete data to a separate file and then when the user exits the app, merely delete that file? There will definitely be overhead with migrating these objects but it may provide for a smoother UX.

于 2012-07-24T04:11:41.780 に答える