web-dev-qa-db-ja.com

NSUserDefaultsに値を保存するのに制限はありますか?

IPhoneの開発は初めてで、Objective C。アプリにいくつかの値を保存するためにNSUserDefaultsを使用しました。しかし、NSUserDefaultsに値を保存するための制限があるかどうかはわかりません。誰でも私がそれを知るのを助けることができます。

前もって感謝します。

62
Johnykutty

IPhone/iPadに十分なスペースがある限り、NSUserDefault値を保存できます。これらの値はすべて.plistファイルに保存され、このファイルは非常に小さく、ほとんどの場合1 kb未満です(大量のデータを保存しない限り)。

49
user914372

保存できる型には制限があります。それらはすべてプロパティリストオブジェクト、つまりNSStringNSNumberNSDataNSArray、およびNSDictionaryでなければなりません。さらに、値がプロパティリストオブジェクトでもある場合、NSArrayおよびNSDictionaryのみを保存できます。また、NSDictionaryのすべてのキーは文字列でなければなりません。

UIColorのようなオブジェクトは上記のリストにないことに注意してください。したがって、デフォルトのデータベースに色を保存する場合は、まず文字列またはデータオブジェクトに変換し、デフォルトを読んだときに元に戻す必要があります。

サイズの制限に関しては、文書化されているものはありませんが、すべてのデータはプロパティリストファイルとして保存されることに注意してください。ファイル全体が全体として読み込まれ、書き出されるため、NSUserDefaultsを使用して、部分的にのみ変化する大量のデータを保存すると、不必要なI/Oを行うことに多くの時間を浪費することになります。

43
benzado

「制限はありますか?」という直接の質問に誰もが答えています。ただし、このスレッドは、「UserDefaultsに格納するには多すぎます?」

あなたがその答えを探しているなら、ここに便利な thread があります。私が役立ったと答えたのは、プロジェクトファイルにアクセスして、plistファイルのサイズを確認することでした。

5つのオブジェクトはほとんど何もありません。大丈夫です!


私のマシンでは、ユーザーのデフォルトで約28メガのデータがあります。それはまったく問題を引き起こしていません。


配列に関する一般的なプログラミングの経験から、要素のサイズに応じて、1000に達するとパフォーマンスが急速に低下し始めると思います。したがって、プログラムでは、数百の要素を保存するのに問題はありません。これは、もし私があなただったなら、私はおそらくsqlite3データベースまたはcoredataの使用を後からではなく早めに使い始めるだろうと言っていました。

覚えておくべき重要:

上記により、増え続けるデフォルト(現在は約20から25)が問題を引き起こすという懸念が軽減されました。私はすでにCoreDataを使用しているので、許可されているユーザー設定/カスタマイズの数が増え続けているため、どちらを使用するかを検討していました。そのため、ユーザーのデフォルトのままにします。

ただし、、他の回答が指摘しているように、ファイルは全体として読み書きされます。したがって、1つの文字列を取得するためだけに20個のキー/文字列辞書と5個のキー/ブール辞書を読み取ることは、理想的ではありません。それでも、パフォーマンスを低下させず、大量のコードを節約できるのであれば、なぜですか?

9
Dave G

NSUserDefaultsに値を保存するための制限はありません。

4
Manmay

IOS SDKコード、および related Apple公式ドキュメント。 から。

extension UserDefaults {


    /*!
     NSUserDefaultsSizeLimitExceededNotification is posted on the main queue when more data is stored in user defaults than is allowed. Currently there is no limit for local user defaults except on tvOS, where a warning notification will be posted at 512kB, and the process terminated at 1MB. For ubiquitous defaults, the limit depends on the logged in iCloud user.
     */
    @available(iOS 9.3, *)
    public class let sizeLimitExceededNotification: NSNotification.Name


    // ....
 }   


概要

  1. 現在、ローカルユーザーのデフォルトに制限はありません
  2. tvOSでは、警告通知が512kBで投稿され、プロセスは1MBで終了します。
  3. ユビキタスなデフォルトの場合、制限はログインしたiCloudユーザーに依存します。
4
AechoLiu

多くの人が既に述べたように、.plist(例:UserDefaults)にデータを保存するためのサイズ制限(物理メモリを除く)を認識していません。したがって、それはどのくらいの問題ではありません。

実際の質問は、新しい値や変更された値をどのくらい頻繁に書き込むかです。そして、これは、この書き込みが引き起こすバッテリーの消耗に関連しています。

IOSは、データの整合性を保つために、単一の値が変更された場合に「ディスク」への物理的な書き込みを回避する機会がありません。 UserDefaultsに関しては、これによりファイル全体がディスクに書き換えられます。

これにより、「ディスク」の電源がオンになり、長時間電源がオンになり、IOSが低電力状態になるのを防ぎます。

「iOSアプリのエネルギー効率ガイド」から:

データ書き込みを最小限に抑えます。内容が変更された場合にのみファイルに書き込み、可能な限り単一の書き込みに変更を集約します。 数バイトしか変更されていない場合、ファイル全体を書き出すことは避けてください。頻繁に小さな部分を変更する場合大きなファイルの場合は、代わりにデータベースを使用してデータを保存することを検討してください。

すべての値がメモリにキャッシュされるため、READSは問題ありません。

EDIT:(2019年7月):Jeffry Fultonによるこの非常に良いブログ投稿を見つけました。

https://jeffreyfulton.ca/blog/2018/02/userdefaults-limitations-and-alternatives

彼は、ユーザーのデフォルトのさまざまな側面について詳しく説明し、いくつかのパフォーマンステストについても書いています。

4
Hardy_Germany

NSUserDefaultsの唯一のStorage Limitationは、Device Storage Capacityです。

Storage SpaceiOSDevice、実質的にNSUserDefaultsにデータを保存できます。 key-valueペアは、格納されているxml構造化ファイル(.plist)に格納されていますApp Bundle

ユーザーデフォルトシステムとキーバリューストアはどちらも単純なデータ型を保存するために設計されています-stringsnumbersdatesBoolean値、[〜#〜] url [〜#〜] s、dataオブジェクトなど、プロパティリスト。プロパティリストを使用すると、配列型と辞書型を使用して設定データを整理することもできます。最初にNSDataオブジェクトにエンコードすることにより、プロパティリストに他のオブジェクトを格納することもできます。

4
Adromil Balais

私の知る限り、NSUserdefaultsに保存するための制限はありません。

2
Tendulkar

ドライブ上の最大許容ファイルサイズに関係なく。このコードを使用して確認できます!

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myKey = @"key";
int sizeOfFile = 1024; // Fill in proper file size here
NSData myObject;
NSString *someFilePath = @"PathToYourFileHere";

for(int i = 1; i < 9999999999999999; i++)
{
  myObject = [NSData dataWithContentsOfFile:someFilePath];
  [defaults setObject:myObject forKey:[NSString stringWithFormat:@"%@%i", myKey, i]];
  NSLog(@"Iteration: %i, TotalWritten: %i", i, i * sizeOfFile);
}
0
Esqarrouth