Why is NSUserDefaults used in iOS?

24

我是iOS开发以及移动应用程序开发的新手,对Objective C和使用MVC模式有相当了解,但我从未进行过任何Mac开发。

我很难理解NSUserDefaults的作用是什么?

我们已经有了像PList这样将数据存储为XML的东西,也有SQLite作为轻量级数据库适用于此类设备。

那么我们为什么还需要它呢?

它是否是我们应用程序中的一种替代简单键值存储方式,就像我们在云上拥有不同类型的存储(例如关系型数据库和基于键值的NoSQL存储)一样?

关于NSUserDefaults,苹果的文档说:

“应用程序通过为用户默认数据库中的一组参数分配值来记录这些首选项”

他们所说的用户默认数据库是什么意思?

我的猜测是,就像在任何多用户操作系统中,我们有各种用户帐户,在Mac中也可能有多个用户,每个用户都有一个数据库,应用程序会从中加载该用户保存的首选项。

因此,类似于Mac OS X,iOS是否也有多个用户,并根据登录的用户选择其首选项?

如果我错了,请告诉我。


看看这个:http://jayprakashdubey.blogspot.in/2014/07/nsuserdefault-usage.html - Jayprakash Dubey
5个回答

15

还有一件事情尚未提及:NSUserDefaults支持所有基本的标量类型(float,int,BOOL),以及与plist兼容的类型:NSData,NSString,NSNumber,NSDate,NSArray和NSDictionary。(您已经提到了plist作为一种替代方案 - NSUserDefaults只是应用程序首选项文件夹中标准plist文件的前端。)这使得在几行代码中轻松创建应用程序状态的永久存储成为可能。更好的是,如果您在模型对象上实现了NSCoding,则可以将其归档为NSData并将它们放入NSUserDefaults:

NSData* data = [NSKeyedArchiver archivedDataWithRootObject:arrayOfModelObjects];

[[NSUserDefaults standardUserDefaults] setObject:data forKey:kDefaultsKeyModelObjects];

而且恢复应用程序数据也很简单,只需要

- (void)viewDidLoad
{
    NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:kDefaultsKeyModelObjects];

    arrayOfModelObjects = [[NSKeyedUnarchiver unarchiveRootObject:data] retain];

    // error checking, tell UI to load the new values, etc...
}

(kDefaultsKeyModelObjects是您在某个地方定义的字符串常量。始终将您的NSUserDefaults键放在一个地方!在键名中拼写错误可能需要花费数小时来调试。:)

如果您使用 SQLite 存储应用程序数据,那么就必须编写大量代码来移动模型数据进入和从数据库中出来。如果您处理大量数据、需要高效搜索等,则这是有意义的;但如果它仅仅是例如网络应用程序中的服务器列表,那么将其放入 NSUserDefaults 更加容易和清晰。

最后一件事:NSUserDefaults 适用于原型制作。即使您知道最终需要 SQLite 存储,您也可以开始使用 NSUserDefaults 作为快速简便的持久存储,让您的用户界面工作并完善数据模型之后,再编写大量的数据库代码。

那么像 Mac OS X 一样,iOS 是否也有多个用户,根据不同用户登录,NSUserDefaults 可以选择他/她的偏好设置吗?

不,iOS 中默认 plist 文件位于应用程序的 Library/Preferences 文件夹中,而不是像 OS X 中那样位于特定于用户的文件夹中。我无法想象 iOS 会有多个登录,但你永远不知道。如果确实有多个登录,则必须为不同的用户创建单独的默认 plist 文件。


14

NSUserDefaults被用于保存应用程序运行所依赖的小数据部分,而其他方法则适用于储存应用程序需要处理的大量数据。

NSUserDefaults使得这个过程变得非常简单,因为你不必担心文件、实体、检索等等。所有这些只需要一行代码就可以完成。


1
我在NSUserDefaults中存储了一些值,以便在应用程序重新启动时使用。但是,在长时间重新启动应用程序后,有时会得到nil值。 - freelancer
这是一个问题吗?请写一个新的问题,包含所有相关代码,因为NSUserDefaults应该永久存储信息。 - vikingosegundo

4

NSUserDefaults最初是用于存储设置的,但如果根据SO上的问题来看,它似乎被滥用于许多其他事情。它提供了一种单行数据持久性和检索方法,适用于各种数据类型。

iOS上没有内置多用户配置(尚未?)(您是否曾经需要登录到您的iPhone?),但由于OS X和iOS建立在相同的基础之上,因此两个操作系统都使用同一个类。


所以NSUserDefaults在MacOSX中的作用是将设置存储为键值对,存储在用户默认数据库中,应用程序可以从中获取数据。但是告诉我,在iOS中它只是一个简单的键值存储,因为只有一个用户,所以NS“User”Defaults这个名称在这里没有意义?毫无疑问...它被(滥)用了:P那么它在iOS中的用例究竟是什么?抱歉有点傻,但我没有iPhone。我在大学期间做了很多Web开发,现在在公司里要处理iOS。 - Amogh Talpallikar
这应该被选为正确答案。原问题是:“那么像Mac OS X一样,iOS是否也有多个用户,并且根据登录的用户选择他/她的偏好设置?”另一个答案没有回答这个问题。 - user523234

3

iOS是一个单用户操作系统。因此,在OSX和iOS中,NSUserDefaults的使用方式不同。

在iOS中,通常使用NSUserDefaults将应用程序首选项和/或用户数据保存在“iOS默认系统”上。在默认系统中保存的数据将始终持久存在,即使您重新启动iOS设备,甚至用户更新应用程序也是如此。

通常,您应该使用NSUserDefaults来保存应用程序首选项/设置。任何其他大量数据,例如游戏数据或实时计算,都应该保存在文档目录中的CoreData或sqllite中。


@AnkitJain 另一个线程表明这不是真的,除了故障情况:https://dev59.com/lXI-5IYBdhLWcg3w3cg8 - Dave

1

NSUserDefaults 仅为您的应用程序存储值。

请注意 - 它不是传统数据存储(Core Data、SQLite、Property Lists等)的替代品,这些存储方式适用于存储应用程序数据。 NSUserDefaults 的用途是用于特定的键值对。

例如,我使用它来存储经过身份验证的用户的网络ID和全名,一旦登录过程完成。在会话超时或注销时,我清除这些值。对于此类情况,NSUserDefaults 是非常有用的。


NSUserDefaults是应用程序会话的一种临时存储,类似于Web应用程序中的会话存储吗? - Amogh Talpallikar
不,NSUserDefaults是用于持久存储的,完全相反于临时存储。如果您希望数据始终存在,并且数据量相对较小,则可以将其保存在NSUserDefaults中。比如说,您正在开发一款游戏,您的应用程序包含一个设置视图,供用户选择选项,例如“昵称”,颜色,速度等,则应使用NSUserDefaults来保存这些用户首选项。您也可以使用plist和sql-lite,但大多数iOS开发人员建议使用NSUserDefaults来进行应用程序设置的最佳实践。 - Semere Taézaz Sium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接