iOS4 アプリケーションの状態遷移

※7/1: キーとなる状態と遷移の説明を追記しました。


iOS4 からアプリケーションのマルチタスク動作が可能になりました。これに伴い、iOS4 ではアプリケーションに新しい状態やイベントが追加されています。ここでは、iPhoneAppProgrammingGuide 4.0 2010-06-04 版 [1] を元にして、新しいアプリケーションの状態遷移をまとめてみます。(まだ、理解しきれていない部分もありますが、自分の理解のまとめという意味でひとまず)


注意:ここで言うアプリケーションの「状態」とは、UIApplicationStateが表す状態や、[1] の P29 Table 2-3にある Application statesとイコールではありません。Launchingや Terminating、Active, Inactive状態のスーパー状態としての Foreground状態など、iOS4で追加されたイベントや仕様を理解しやすくなるように拡張したものです。



図1 iOS4のアプリケーションの状態遷移


図1は iOS4のアプリケーションの状態遷移を表しています。図は UMLで記載しています。遷移アクションの willXXX, entryアクションおよび exitアクションの didXXXは UIApplicationDelegate で定義される delegateメソッドです。アプリケーションはこれらの delegateメソッドを定義することで状態の変化を検知できます。


以下は状態の一覧です。

State 概要
Launching アプリケーションの起動状態。初回の起動後は Foreground状態に遷移する。VoIPのようにバックグラウンド処理のために iOSから起動された場合は Background状態に遷移する。
Active 画面のタッチイベントなどユーザ操作を受信し処理可能な状態
Inactive 着信やSMS受信などシステムからの割り込みがあるとこの状態に遷移する。アプリケーションは動作可能だがタッチイベントなどの受信はできない。
Executing バックグランドタスクを実行している状態。タスクを完了すると Suspendedに遷移する。何もタスクがない場合は即座に Suspendedに遷移する。
Suspended 休止状態。この状態のアプリは何も処理を行っていないが、アプリが使用しているメモリは保存されており、アプリを再起動すればすぐに復帰できる。ただし、システム全体のメモリが不足すると、事前通知なく自動的に killされる
Terminating アプリケーションの終了状態。従来の iOS3のようにマルチタスク動作しない場合にのみこの状態に遷移する。


図のうち、Background状態と Background状態を出入りするイベントを取り除くと従来の iOS3におけるアプリケーションの状態遷移になります。つまり、Background状態とそれに関連する状態遷移がマルチタスク動作のキーということになります。次にこれらキーポイントについて見ていきます。

Foreground状態から Background状態へ

iOS3においては Foreground状態からの遷移とはアプリケーションの終了を意味します。この場合、アプリケーションは図1 の Terminating状態に遷移し、一般的なアプリケーションは willTerminateアクションにより終了を検知し、データ保存などの後処理を行ないます。

iOS4においてマルチタスクに対応したアプリケーションは、Foreground状態から Background状態に遷移します。この場合、willTerminateメッセージが通知されることはありません。willTerminateで行っていた後処理は、didEnterBackgroundアクションのようなSuspended状態に遷移するよりも前のタイミングで処理します。Suspended状態に遷移するとアプリケーションは一切の処理を実行できなくなり、メモリ不足になると通知されることなくアプリケーションが終了してしまうためです。

Background状態から Foreground状態へ

アプリケーションが利用するメモリや UIオブジェクトは Background状態である間も保持されます。このため、単純に元の Foreground状態に戻すだけであれば、アプリケーションは何もする必要がありません。画面やメモリは Background状態に移行する前のものにそのまま復元されます。

しかし、多くのアプリケーションにとってはこのような単純な復元では不十分です。アプリケーションがBackground状態である間に、iOSシステムやユーザの設定、クラウドサービスの状態は刻々と変化します。たとえば、多言語対応したアプリケーションであれば Foreground状態に復帰したタイミングで言語環境の設定が変更されていないかを監視し新しい言語で画面をアップデートすべきです。位置情報を利用するアプリケーションやクラウドサービスのクライアント・アプリケーションも同様に、最新の状態に追従することを求められるでしょう。

Background状態のサブ状態とバックグラウンド処理

Background状態では、まずバックグラウンド処理を実行する Executing状態となり、処理が完了すると Suspended状態に遷移します。バックグラウンド処理が何もなければすぐに Suspended状態に遷移します。
バックグラウンド処理を行うには、バックグラウンド処理の開始と終了をアプリケーションからシステムに明示的に宣言する必要があります。この宣言がないと、何か実行中の処理があったとしても強制的に Suspended状態に移行されてしまいます。beginBackgroundTaskWithExpirationHandler:メッセージがバックグラウンド処理の開始を、endBackgroundTask:メッセージが終了を表します(メソッドの詳細は Programming Guideを参照)。iOSではバッテリー消費や CPU負荷を軽減するため、バックグラウンド処理可能な時間には、10分という制約があります。endBackgroundTask:メッセージがなくても、この規定時間を超えたアプリケーションは例外ハンドラがコールされたあと Suspended状態に移行します。(強制終了される?)


以上、iOS4におけるアプリケーション状態遷移のまとめでした。