我在应用程序中使用了NSUserDefaults
来存储一些值。在NSUserDefaults
中存储值是否有限制?
我在应用程序中使用了NSUserDefaults
来存储一些值。在NSUserDefaults
中存储值是否有限制?
存储的数据类型有限制:必须全部是属性列表对象,包括NSString
、NSNumber
、NSData
、NSArray
和NSDictionary
。此外,如果要存储NSArray
和NSDictionary
,则其中的值也必须是属性列表对象;而且NSDictionary
中所有的键值都必须是字符串。
请注意,像UIColor
这样的对象不在上述列表中。因此,如果您想将颜色存储在默认数据库中,您需要先将其转换为字符串或数据对象,然后在读取默认值时再将其转换回来。
至于大小限制,没有文档说明,但请注意所有数据将作为属性列表文件存储。整个文件会被一次性地读入和写出,因此如果您使用NSUserDefaults
来存储大量仅在部分更改的数据,那么您将浪费很多时间进行不必要的I/O操作。
通过iOS SDK代码和相关的苹果官方文档。
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
// ....
}
大家都回答了“有没有限制”的直接问题。然而,我找到这个帖子是为了理解在UserDefaults中存储多少才算过多。
如果你正在寻找答案,这里有一个有用的帖子。我发现有用的回答是去项目文件中查看plist文件的大小:
5个对象几乎什么都不是。你会没问题的!
在我的机器上,我有大约28兆字节的数据在我的用户默认中。这根本不会引起任何问题。
从数组的一般编程经验来看,当你进入1000多个元素时,性能开始快速下降,这取决于元素大小。因此,在我的程序中,我不会有问题存储几百个元素。话虽如此,如果我是你,我可能会尽早开始使用sqlite3数据库或coredata。
需要记住的重要事情:
以上内容解除了我对于增长中的默认值(现在大约20-25个)是否会引起问题的担忧。我已经在使用CoreData,所以我正在考虑应该使用哪一个,因为我的允许用户首选项/自定义的数量正在增加。所以,我将继续使用UserDefaults。
然而,正如其他答案指出的那样,该文件将作为一个整体读取和写入。因此,读取20个键/字符串字典和5个键/布尔字典只是为了检索一个字符串...并不完美。尽管如此,如果它不会影响性能并且可以节省大量代码,为什么不呢?
https://jeffreyfulton.ca/blog/2018/02/userdefaults-limitations-and-alternatives
他详细描述了用户默认设置的不同方面,并写了一些性能测试。从 iPadOS 13.1 beta 3 开始,当试图存储一个较大的对象(如图片)时,我现在会看到以下消息:
2019-09-14 11:01:29.634368+0100 MyApp[1686:147223] [用户默认设置] CFPrefsPlistSource<0x283c7d980> (域名: com.example.MyApp, 用户: kCFPreferencesCurrentUser, ByHost: No, 容器: (null), 内容 不需要刷新: No): 在此平台上尝试将 >= 4194304 字节的数据存储在 CFPreferences/NSUserDefaults 中是无效的。 这是 MyApp 或其使用的库中的错误。
但是检索密钥似乎仍然有效。
synchronize
。正如文档中所述,“这个方法是不必要的,不应该被使用。” - DougNSUserDefaults
中唯一的存储限制是设备存储容量。只要在iOS
设备上有可用的存储空间,就可以实际上将数据存储在NSUserDefaults
中。键值对存储在一个xml结构文件(.plist)中,并存储在一个应用程序包中。
用户默认系统和键-值存储都是为存储简单数据类型而设计的——如字符串、数字、日期、布尔值、URL、数据对象等,这些数据以属性列表的形式存储。使用属性列表还意味着您可以使用数组和字典类型来组织您的首选项数据。也可以通过首先将它们编码成
NSData
对象来将其他对象存储在属性列表中。
NSUserDefaults中存储值没有限制。
无论驱动器上允许的最大文件大小是多少,您都可以使用此代码片段进行检查!
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);
}
int
值无法达到那么高的范围,因此在循环中迭代次数超过大约 21.5 亿之后,你将遇到溢出问题。不过,在那之前,你会先遇到 sizeOfFile
的溢出问题。 - Stonz2