Objective-CなどiOS関連の技術メモ。知識はここに投げ捨てて忘れる。

NSUserDefaultsのsynchronizeは明示的に呼ぶべきか

最終更新日 2013年12月20日 21:58

NSUserDefaultsは、毎回ストレージ(フラッシュドライブなど永続的なやつ)にアクセスするのを避けるため、メモリ上に設定値情報をキャッシュしている。メモリ上の設定値情報をストレージに書き込む役割をもつのが、synchronizeメソッドである。synchronizeメソッドは明示的に呼び出さなくても、ランタイムによって一定間隔ごとに自動的に呼び出される。

At runtime, you use an NSUserDefaults object to read the defaults that your application uses from a user’s defaults database. NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. The synchronize method, which is automatically invoked at periodic intervals, keeps the in-memory cache in sync with a user’s defaults database.

NSUserDefaults Class Reference

実行環境依存なので確かなことは言えないが、実際には一定間隔ごとではなく、アプリがバックグラウンドに移動したときなどのイベント発生時に呼び出されているようである。AppDelegateに次のようなコードを書いてsynchronizeメソッド呼出をフックすれば、実行タイミングを確かめることができる。

バックグラウンドへの移動タイミングでsynchronizeが呼ばれるのなら、バックグラウンドで何もしないアプリであればアプリ終了前も含めて明示的なsynchronize呼び出しがなくても、おおむね正常に動作することになるが、これには次のような問題がある。

  • アプリがバックグラウンドに移動するタイミングでsynchronizeが呼び出されるのは仕様で定められているわけではない(この振る舞いに依存するコードを書く訳にはいかない)
  • アプリがクラッシュした場合、synchronizeは呼ばれない

どちらもかなり問題なので、「synchronizeを明示的に呼ばない」という選択肢はなさそうである。データを更新したときは常にsynchronizeを実行しておくべきだろう。

詳解 Objective-C 2.0 第3版

必読。こんなゴミサイトより、こっちを読むべき。

Amazonでみる

iPhoneプログラミングUIKit詳解リファレンス

必読。こんなゴミサイトより、こっちを読むべき。

Amazonでみる