iOSで「他のアプリを終了してください」はEvilである

iPhoneを使っていると次のようなメッセージを時々見る。

20140225-082227.jpg

ゲーム系のアプリでよく見るけど、要は「このアプリが使うメモリが足りないから他のアプリを殺せ!」と言っているわけで。
このメッセージ、正しいけど間違ってる。

iPhoneに搭載されているメモリは限られている。その限られているメモリを色々なアプリでシェアしながら使っている。
自分が使うメモリが足りない場合はどうするのか?答えは単純で、他のアプリが使うメモリを奪えばいい。だから、このメッセージは正しいわけである。

ただし、注意することがいくつかある。このメッセージはそれを伝えていないから間違っていると言える。

iPhoneに搭載されているOS、「iOS」はそれぞれのアプリケーションの動作を細かくチェックしている。
そのチェックする機構の中に「メモリを管理する」機能も含まれいて、iOSは「今、メインで動いているアプリのメモリが足りなければ他のアプリを終了する」という動作をする。
つまり、自分が使うメモリが足りなくてもiOSが勝手にやりくりしてメモリを調達してくれるため、ユーザーが他のアプリを自分で終了させる必要は無いのである。

それでもいくつかのケースでメモリのやりくりが間に合わないケースがある。例えばゲームの開始時にマップやキャラクタのデータを一気に読み込んで急にメモリが大量に必要になった場合にはiOSのメモリのやりくりが間に合わずにアプリがクラッシュしてしまう。これを避けるためにメモリが足りなさそうな場合は上記のような「他のアプリを殺せ!」というメッセージを出して、あらかじめメモリに余裕を持たせようとしているのであろう。

前置きが長くなったが、ここからが本題。

最も重要なことはiOSがメモリのやりくりで他のアプリを終了させた場合とユーザーが自分で他のアプリを終了させた場合の挙動が異なるということである。

挙動が異なることによる最も大きな問題としては、バックグラウンドで動くアプリが自動的に起動しなくなることが挙げられる。
先に挙げたように、iOSがメモリのやり繰りをする中で、メモリが足りなくなった場合は他のアプリを終了させる。しかし、メモリに余裕ができ、バックグラウンドで動作するアプリが起動を必要とする時点でiOSはそのアプリを再起動させ、動作を継続させようとするのである。ただし、あくまでこれはiOSが判断して終了させた場合で、ユーザーが自分の判断で終了させた場合にはiOSが自動的に再起動させることはない。ここに十分な注意を払う必要がある。

具体例を挙げると、ライフロガー系のアプリが動かなくなることが分かりやすいかもしれない。

Movesというアプリがある。最近、Facebookに買収されたことでも話題になったが、GPSを使って自分がどこをどう移動したのか、どれほどの時間を滞在したのかを自動的に記録するアプリである。

このアプリはiOSが提供するロケーションサービスという位置情報を扱う仕組みを利用しており、一定の移動を行うごとにiOSから通知される位置情報を記録している。そのため、Movesがバックグラウンドにいる間でもずっと起動しており、その挙動はiOSによって管理されている。

例え、メモリが不足してiOSがMovesを終了させた場合でも、次に位置情報が更新されてMovesにそれを通知する必要が発生したタイミングでiOSはMovesを再起動させる。これにより、Movesは継続して位置情報を記録し続けることができる。

しかし、ユーザーが自分で判断してMovesを終了させた場合は、本来はiOSが位置情報を通知すべきタイミングになってもMovesは再起動されない。よって、Movesはそれ以降の記録を取ることができなくなるのである。これはユーザーにとっては不幸な事態と言えるだろう。

シナリオを考えてみよう。

1. ユーザーはMovesを使って、常に自分のライフログを取っている。
2. ユーザーはゲームを開始する。
3. 「メモリが不足しているから他のアプリを終了しろ」というメッセージに従い、Movesを終了させた。
4. ゲームを楽しんだ後、ユーザーは日常生活に戻り、移動を繰り返した。
5. ユーザーは自分のライフログを確認しようとして、Movesを起動した。
6. しかし、ゲームをした時以降のライフログは残っていない
7. 最悪の場合、ユーザーはこれをMovesの不具合と判断する。そしてMovesは使えないアプリの烙印を押され、☆1レビューを書かれる

これはユーザーにとっても、Movesの開発者にとっても不幸なことである。
ユーザーの無知、そして「アプリを終了しろ」とメッセージを出すアプリの無責任によって引き起こされた悲しい事態である。

もちろん、ユーザーが改めて明示的にMovesを起動した場合、それ以降は再びiOSの管理下に置かれ、バックグラウンドでの動作が可能になる

まとめよう。

1. ユーザーはアプリを明示的に終了させる必要はない。iOSが管理してくれる。
2. アプリは他のアプリを終了させることを促してはいけない

アプリの開発者は、iOSに搭載されているメモリは自分だけの物ではないという自覚を持ち、できるだけメモリの消費量を抑えよう。
どうしても多くのメモリが必要な場合は、iOSの再起動を促すのが良い。再起動直後ならば最大限の余裕は持てる。

ユーザーも開発者も、皆が幸せになれますように。

2014/05/12 タイトルを一部変更。