NSUserDefaults有哪些限制?

时间:2011-05-30 07:52:18

标签: iphone objective-c core-data nsuserdefaults

通常使用Core Data或sqlite3在iPhone中永久存储数据。大多数人更喜欢将NSUserDefaults用作应用程序首选项的存储,而不是将其用作普通数据库(例如sqlite)。

我发现大量数据可以存储在NSUserDefaults中,它非常易于使用且速度很快。那么为什么不将它用作永久存储? NSUserDefaults作为数据库有哪些限制?

更新
我经常使用三种不同的方法将数据保存到磁盘。

  • 核心数据
  • 将对象序列化为plists
  • NSUserDefaults的

我不再使用FMDB(或直接使用sqlite)了。 每种方法的主要优点和缺点是什么?

我遇到的NSUserDefaults的一些优点:

  • 使用NSPredicate可以轻松完成排序,分组等操作。
  • NSUserDefaults是线程安全的。
  • 获取NSAserDefaults并将数据保存到NSUserDefaults需要一行。

4 个答案:

答案 0 :(得分:16)

Sqlite3对于保留大型数据库和访问数据库元素更有用。您可以对Sqlite3数据库中的项进行排序,您可以在Sqlite3 dtabase中快速搜索项。 Sqlite3数据库有许多NSUserDefaults没有的权限!


NSUserDefaults vs Sqlite3

NSUserDefaults用于用户首选项,通常是NSString或NSNumber等基本对象。 Sqlite,序列化属性列表中的对象集合,或核心数据都是存储用户数据的有效选项,例如您创建的模型对象。

你不会看到速度差异,但仍然最好为你正在做的事情选择正确的机制。如果它只是首选项,那么使用NSUserDefaults,否则我会将您的对象序列化为plist。如果你是Cocoa的新手,我会首先避免使用Core Data甚至是Sqlite,让自己有机会先学习基础知识。


NSUserDefaults or Sqlite

如果要存储大量具有某种关系的数据,如果要为NSUserDefaults存储较少的值,请选择Sqlite。 Sqlite占用了一些内存,因此只有在真正需要保存复杂数据时才使用它。


Using NSUserDefaults to save a lot of game data

通常NSUserDefaults用于保存游戏设置。要保存游戏数据,通常最好使用SQLite,或者您可以创建对象的NSDictionary并保存到磁盘,这里有几个可能有用的帖子:

  1. <击> http://www.cocos2d-iphone.org/forum/topic/9308
  2. <击> http://www.cocos2d-iphone.org/forum/topic/9210

答案 1 :(得分:9)

NSUserDefaults提供了一个简单的学习曲线和线程安全实现。

否则我发现Core Data在各方面都很出色。特别是在配置默认值和迁移例程方面。

编辑:事实证明,NSUserDefaults“线程安全”似乎来自主线程上的运行操作。这导致我的一个应用程序严重跳帧;我最终剥离了NSUserDefaults并将其替换为一个线程安全的NSMutableDictionary,它被序列化为一个文件。

答案 2 :(得分:4)

对于我目前正在进行的项目,我需要建立一个大型数据库(大约400,000条记录)。如果使用NSUserDefaults,则必须添加记录,这可能需要几分钟(取决于设备和导入数据的方式)。如果您使用CoreData,您只需将预构建的数据库复制到应用程序的文档目录中并立即使用它。

这就是我依赖CoreData的原因。

答案 3 :(得分:1)

CoreData的一个优点是您的对象将是具有属性的NSManagedObject。这意味着当您获得或设置值时,您将自动完成以帮助您使用属性名称。它还使代码更具可读性。

与NSUserDefaults同时,您必须始终使用键值访问器,使用键的字符串。

即:

myGlobalSettingsObject.lastLoginTime = @(now);

VS

[[NSUserDefaults standardUserDefaults] setValue:@(now) forKey:@"lastLoginTime"];

如果您在某处设置密钥时不小心弄错了怎么办?编译器不会警告你。如果有人在某个地方输错了怎么办?编译器不会警告你。

E.g:

[[NSUserDefaults standardUserDefaults] setValue:@"now" forKey:@"lastLoginTiem"]; ^ ^ ^^^^

...在构建时不会引起警告或错误......危险!

使用NSManagedObject的其他好处是它可以进行验证;它可以确保非空值;它可以有自定义的getter和setter方法,你可以用来做一些很酷的东西;如果你改变了存储值的方式,它可以处理自动迁移;并且其数据模型成为您的存储库的一部分,因此您可以轻松跟踪其更改的历史记录。

与此同时,NSUserDefaults快速而且肮脏,非常适合基本的小应用程序,但它只是非常原始的。适用于小型应用程序,但如果您拥有庞大的应用程序,与使用Core Data相比,它将变得难以管理。

关于NSUserDefaults唯一可能的事情是,如果你的应用需要删除它的CoreData商店,或者你不想为实现线程安全的CoreData而烦恼,那么这方面的维护就会降低。