ios 在 NSUserDefaults 中存储值有什么限制吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7510123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:35:47  来源:igfitidea点击:

Is there any limit in storing values in NSUserDefaults?

iphoneobjective-ciosxcodensuserdefaults

提问by Johnykutty

I am new to iPhone development and objective C. I have used NSUserDefaultsto store some values in my app. But I don't know that if there is any limit for storing values in NSUserDefaults. Can anyone help me to know that.

我是 iPhone 开发和objective C. 我曾经NSUserDefaults在我的应用程序中存储一些值。但我不知道在NSUserDefaults. 任何人都可以帮助我知道这一点。

Thanks in advance.

提前致谢。

采纳答案by Johnykutty

As long as there's enough space on the iPhone/iPad, you can store NSUserDefault values. All those values is stored into a .plist file, and this file is very small, most of the time under 1 kb (unless you store a lot of data).

只要 iPhone/iPad 上有足够的空间,就可以存储 NSUserDefault 值。所有这些值都存储在一个 .plist 文件中,这个文件非常小,大部分时间都在 1 kb 以下(除非你存储了很多数据)。

回答by benzado

There are limits on what types you may store: they must all be Property List objects, namely NSString, NSNumber, NSData, NSArray, and NSDictionary. Furthermore, you may only store NSArrayand NSDictionaryif the values are also property list objects; also, all the keys of the NSDictionarymust be strings.

还有你可以存储什么类型的限制:它们必须属性列表对象,即NSStringNSNumberNSDataNSArray,和NSDictionary。此外,如果值也是属性列表对象,则只能存储NSArrayNSDictionary;此外,所有的键都NSDictionary必须是字符串。

Note that an object like UIColoris not on the above list. So if you want to store a color in the defaults database, you'll need to convert it into a string or data object first, then convert it back when you read the defaults.

请注意,像这样的对象UIColor不在上面的列表中。因此,如果要将颜色存储在默认数据库中,则需要先将其转换为字符串或数据对象,然后在读取默认值时将其转换回。

As far as size limits, there are none that are documented, but note that all data will be stored as a property list file. The entire file is read in and written out as a whole, so if you use NSUserDefaultsto store a large amount of data that only changes in parts, you will be wasting a lot of time doing unnecessary I/O.

至于大小限制,没有记录在案,但请注意,所有数据都将存储为属性列表文件。整个文件是作为一个整体读入和写出的,所以如果你NSUserDefaults用来存储大量只有部分变化的数据,你会浪费大量时间做不必要的I/O。

回答by Dave G

Everyone has answered the direct question of "is there a limit?" However, I found this thread really looking to understand "how much is too muchto store in UserDefaults?"

大家已经回答了“有没有限制”的直接问题。然而,我发现这个线程真正看明白“是多少太多存储在UserDefaults?”

If you're looking for that answer, here's a useful thread. The responses I found helpful were to go to your project file and look at the plist file size:

如果您正在寻找该答案,这里有一个有用的线程。我发现有用的回复是转到您的项目文件并查看 plist 文件大小:

5 objects is almost nothing. You'll be fine!

5个对象几乎没有。你会没事的!



On my machine, I have about 28 megs of data in my user defaults. That's not causing any problems at all.

在我的机器上,我的用户默认值中有大约 28 兆的数据。这根本不会造成任何问题。



From general programming experience with arrays I would guess performance starts to rapidly decay when you get into 1000's, depending on element size. Therefore in a program I wouldn't have an issue storing a couple of hundred elements. This said I would probably start using a sqlite3 database or coredata, sooner rather than later if I were you.

根据对数组的一般编程经验,我猜当您进入 1000 时,性能开始迅速下降,具体取决于元素大小。因此,在程序中我不会有存储几百个元素的问题。这表示如果我是你,我可能会开始使用 sqlite3 数据库或 coredata,宜早不宜迟。

Important to remember:

重要的是要记住:

The above alleviated my concerns that my growing number of defaults (about 20-25 now) would cause problems. I use CoreData already, so I was considering which to use since my number of allowed user preferences/customizations is growing long. So, I'm going to stay with user defaults.

以上减轻了我对我越来越多的默认值(现在大约 20-25 个)会导致问题的担忧。我已经在使用 CoreData,所以我正在考虑使用哪个,因为我允许的用户首选项/自定义的数量越来越长。所以,我将保留用户默认设置。

However, as other answers have pointed out, the file will be read and written as a whole. So reading 20 key/string dictionaries and 5 key/boolean dictionaries just to retrieve one string... not exactly ideal. Nonetheless, if it doesn't hurt performance and it saves you a ton of code, why not?

但是,正如其他答案所指出的那样,该文件将作为一个整体进行读取和写入。所以阅读 20 个键/字符串字典和 5 个键/布尔字典只是为了检索一个字符串......并不完全理想。尽管如此,如果它不影响性能并且为您节省大量代码,为什么不呢?

回答by AechoLiu

From iOS SDK codes, and related Apple official document..

来自 iOS SDK 代码,以及相关的 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


    // ....
 }   




Summary

概括

  1. Currently there is no limit for local user defaults
  2. On tvOS, where a warning notification will be posted at 512kB, and the process terminated at 1MB.
  3. For ubiquitous defaults, the limit depends on the logged in iCloud user.
  1. 目前本地用户默认没有限制
  2. tvOS 上,警告通知将在 512kB 处发布,进程在 1MB 处终止。
  3. 对于无处不在的默认设置,限制取决于登录的 iCloud 用户。

回答by Adromil Balais

The only Storage Limitationin NSUserDefaultsis the Device Storage Capacity.

唯一的存储限制NSUserDefaults设备的存储容量

As much as there are available Storage Spacein an iOSDevice, you can practically store data in NSUserDefaults. The key-valuepair is stored on a xml structured file (.plist) which is stored in an App Bundle.

尽可能有可用的存储空间中的设备,你几乎可以存储数据。的-对存储在一个XML结构的文件(plist中其被存储在一个)应用程序包iOSNSUserDefaults

The user defaults system and key-value store are both designed for storing simple data types—strings, numbers, dates, Booleanvalues, URLs, dataobjects, and so forth—in a property list. The use of a property list also means you can organize your preference data using array and dictionary types. It is also possible to store other objects in a property list by encoding them into an NSDataobject first.

用户默认系统和键值存储都设计用于在属性列表中存储简单的数据类型——字符串数字日期布尔值、 URL数据对象等等。使用属性列表还意味着您可以使用数组和字典类型组织您的首选项数据。还可以通过首先将其他对象编码到一个对象中来将其他对象存储在属性列表中。NSData

回答by Doug

As of iPadOS 13.1 beta 3, I'm now seeing the following message when trying to store a larger object (an image).

从 iPadOS 13.1 beta 3 开始,我现在在尝试存储更大的对象(图像)时看到以下消息。

2019-09-14 11:01:29.634368+0100 MyApp[1686:147223] [User Defaults] CFPrefsPlistSource<0x283c7d980> (Domain: com.example.MyApp, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No): Attempting to store >= 4194304 bytes of data in CFPreferences/NSUserDefaults on this platform is invalid. This is a bug in MyApp or a library it uses

2019-09-14 11:01:29.634368+0100 MyApp[1686:147223] [用户默认值] CFPrefsPlistSource<0x283c7d980>(域:com.example.MyApp,用户:kCFPreferencesCurrentUser,Container:ByHost:需要刷新:否):尝试在此平台上的 CFPreferences/NSUserDefaults 中存储 >= 4194304 字节的数据无效。这是 MyApp 或其使用的库中的错误

However retrieving the key appears to still work.

然而,检索密钥似乎仍然有效。

回答by Hardy_Germany

As many already mentioned: I'm not aware of any SIZE limitation (except physical memory) to store data in a .plist (e.g. UserDefaults). So it's not a question of HOW MUCH.

正如许多人已经提到的:我不知道将数据存储在 .plist(例如 UserDefaults)中的任何 SIZE 限制(物理内存除外)。所以这不是多少的问题。

The real question should be HOW OFTEN you write new / changed values... And this is related to the battery drain this writes will cause.

真正的问题应该是你多久写入新的/更改的值......这与写入会导致电池消耗有关。

IOS has no chance to avoid a physical write to "disk" if a single value changed, just to keep data integrity. Regarding UserDefaults this cause the whole file rewritten to disk.

如果单个值更改,IOS 没有机会避免物理写入“磁盘”,只是为了保持数据完整性。关于 UserDefaults 这会导致整个文件重写到磁盘。

This powers up the "disk" and keep it powered up for a longer time and prevent IOS to go to low power state.

这会为“磁盘”加电并使其保持通电更长时间,并防止 IOS 进入低功耗状态。

From "Energy Efficiency Guide for iOS Apps":

Minimize data writes. Write to files only when their content has changed, and aggregate changes into a single write whenever possible. Avoid writing out an entire file if only a few bytes have changed.If you frequently change small portions of large files, consider using a database to store the data instead.

摘自“iOS 应用能效指南”:

尽量减少数据写入。仅在文件内容发生更改时写入文件,并尽可能将更改汇总为一次写入。如果只有几个字节发生了变化,请避免写出整个文件。如果您经常更改大文件的一小部分,请考虑改用数据库来存储数据。

READS are no problem, as all values are cached in memory.

读取没有问题,因为所有值都缓存在内存中。

EDIT:(July 2019): I just found this very good blog post by Jeffry Fulton.

编辑:(2019 年 7 月):我刚刚找到了 Jeffry Fulton 的这篇非常好的博客文章。

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

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

He describes in detail the different aspects of the user defaults and also writes about some performance tests.

他详细描述了用户默认值的不同方面,还写了一些性能测试。

回答by Manmay

There is No Limit for storing values in NSUserDefaults..

在 NSUserDefaults 中存储值没有限制。

回答by Tendulkar

As far as my knowledge there is no limit for storing in NSUserdefaults.

据我所知,在 NSUserdefaults 中存储没有限制。

回答by Esqarrouth

It whatever the maximum allowed file size is on the drive. You can use this piece of code to check it out!

无论驱动器上允许的最大文件大小如何。你可以用这段代码来检查一下!

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);
}