iPad アプリがクラッシュする理由はほとんどわかっていますが、このシナリオを回避する方法が思い浮かびません。アプリはジグソーパズルアプリです。アプリ ストアにあるバージョンよりも安定した動作中のバージョンを入手しましたが、いまだに解決できない厄介な問題があります。
問題の根本は、ユーザー アクティビティと自動保存の間の衝突です。保存では、基本的にパズルの状態がプロパティ リストとして保存されます。プロパティ リストには、とりわけ、パズル内のすべてのパレットの編集と、各パレットについて、そのパレットのすべてのピースの詳細が含まれています。ユーザーのアクティビティによってこれらの詳細が変更される可能性があることを除いて、これはうまく機能します。パレットは基本的に、パズルのピースをサブビューとして含む UIView です。ユーザーは、パレット上でピースを移動したり、パレットからパレットに移動したりできます。
保存プロセスは 2 つのフェーズで動作しています。最初のフェーズはタイマーによって開始されます。このフェーズでは、定期的に、保存が必要なユーザー アクティビティがあるかどうかを確認します。プロパティabortSave
を NO に設定し、繰り返しのないタイマーをトリガーして、フェーズ 2 を開始する前に別の期間待機します。
abortSave
フェーズ 2 では、 NO である限り保存が行われます。
一方、ユーザーが保存に影響する操作を実行すると、abortSave
YES に設定されます。フェーズ 1 とフェーズ 2 の間の遅延は、ユーザー操作を実行するのにかかるよりも長いため、abortSave
NO の場合は安全に保存できるはずです。
このプロセスにより、クラッシュの 95% 程度が解消されましたが、まだクラッシュが発生しています。
もちろん、アプリの適切なパフォーマンスのために、ユーザー アクティビティと保存操作はバックグラウンド スレッドで行われます。
私が遭遇している状況のタイプは、通常、高速列挙中の突然変異、またはそのようなものです。基本的に、保存プロセス中に何らかのユーザー アクションによって変更が行われます。高速に列挙されているオブジェクトをコピーしてからそのコピーで作業しても、役に立ちません。コピーステートメントでエラーが発生することがあります。オブジェクトが配列の場合、高速列挙は使用せず、通常の for ループを使用して配列を処理します。それは少し役立ちます。
この質問が一般的すぎないことを願っています。いくつかのコードを投稿できると思いますが、それが実際にどれほど役立つかはわかりません。そして、私は質問を不必要に混乱させたくありません。
私がまだ行っていないことの 1 つは、別の方法で機能するフラグを使用することです。
saveProcessActive
保存が行われる直前に YES に設定し、保存が終了したら NO に設定します。saveProcessActive
YESの場合、すべてのユーザー アクションを停止する必要があります。このシナリオの問題は、ユーザー アクションの遅延が発生し、ユーザーに表示される可能性がありますが、遅延は重要ではない可能性があることです。の次のチェックまで、保存にかかる時間だけあれば十分ですabortSave
。中止された保存プロセスはsaveProcessActive
、中止要求を確認すると NO になります。より良い解決策はありますか?