iOS UI篇 - NSUserDefaults详解

NSUserDefaults是什么,有什么用处

对于应用来说,每个用户都有自己的独特偏好设置,而好的应用会让用户根据喜好选择合适的使用方式,把这些偏好记录在应用包的plist文件中,通过NSUserDefaults类来访问,这是NSUserDefaults的常用姿势。

如果有一些设置你希望用户即使升级后还可以继续使用,比如玩游戏时得过的最高分、喜好和通知设置、主题颜色甚至一个用户头像,那么你可以使用NSUserDefaults来存储这些信息,如果有更多需求,可以了解数据持久化相关的知识。

具体来说NSUserDefaults是iOS系统提供的一个单例类(iOS提供了若干个单例类),通过类方法standardUserDefaults可以获取NSUserDefaults单例。

如:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSUserDefaults单例以key-value的形式存储了一系列偏好设置,key是名称,value是相应的数据。存/取数据时可以使用方法objectForKey:和setObject:forKey:来把对象存储到相应的plist文件中,或者读取,既然是plist文件,那么对象的类型则必须是plist文件可以存储的类型,正如官方文档中提到的

  • NSData
  • NSString
  • NSNumber
  • NSDate
  • NSArray
  • NSDictionary

而如果需要存储plist文件不支持的类型,比如图片,可以先将其归档为NSData类型,再存入plist文件,需要注意的是,即使对象是NSArray或NSDictionary,他们存储的类型也应该是以上范围包括的。

存/读不同类型数据

比如存/读一个整数、字符串和一张图片:

###存

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@”jack“ forKey:@"firstName"];
[defaults setInteger:10 forKey:@"Age"];

UIImage *image =[UIImage imageNamed:@"somename"];
NSData *imageData = UIImageJPEGRepresentation(image, 100);//把image归档为NSData
[defaults setObject:imageData forKey:@"image"];

[defaults synchronize];

其中,方法synchronise是为了强制存储,其实并非必要,因为这个方法会在系统中默认调用,但是你确认需要马上就存储,这样做是可行的。

###读

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firstName = [defaults objectForKey:@"firstName"]
NSInteger age = [defaults integerForKey:@"Age"];

NSData *imageData = [defaults dataForKey:@"image"];
UIImage *image = [UIImage imageWithData:imageData];

我们通过为三个数据设置key的方式把NSInteger、NSString和UIImage三种数据存储下来,其中图片是通过归档为NSData的方式进行存储的,除此之外,还可以被转为NSNumber或NSString类型。顺便提一句,这里NSInteger没有星号,因为NSInteger根据系统是64位还是32位来判断自身是long还是int类型,并且它也不是一个标准Objective-C对象。

简便方法存取不同类型数据

由上边的例子可以看到一个方法-setInteger:,这跟常用的-setObject:相比设置类型更明确。其实,NSUserDefaults提供了若干简便方法可以存储某些常用类型的值,例如:

- setBool:forKey:
- setFloat:forKey:
- setInteger:forKey:
- setDouble:forKey:
- setURL:forKey:

这将使某些值的设置更简单。

NSUserDefaults域

考虑这么一种情况:

BOOL showTutorialOnLaunch = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShowTutorial"];

这种情况下,当key值@“ShowTutorial”已设置后会运行正确。但如果默认数据库没有这个key的默认值时,将会返回NO,这或许就不一定是你需要的值了,因为无法区分NO和no value,前一段所提到的简便方法大多有这种问题。

解决方式:使用registerDefaults:方法

首先创建一个包含用户偏好设置信息的DefaultPreferences.plist文件,添加到target中。在运行时,app就可以加载这个文件并且把内容传到registerDefaults :

NSURL *defaultPrefsFile = [[NSBundle mainBundle]
URLForResource:@"DefaultPreferences" withExtension:@"plist"];
NSDictionary *defaultPrefs = [NSDictionary dictionaryWithContentsOfURL:defaultPrefsFile];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultPrefs];

注意需要在每次启动app并且没有在user defaules中读取数据的时候调用以上方法,因为registerDefaults:不能把这些默认数据存储到硬盘上,所以application:didFinishLaunchingWithOptions是最合适的地方。
这样做的原因是:默认情况下,应用域是空的,没见键也没有值。当应用第一次设置某项用户偏好设置的值时,相应的值会通过指定的键加入应用域。当通过NSUserDefaults获取某项用户偏好设置的值时,NSUserDefaults会先在应用域中查找,如果找到了值,NSUserDefaults就会返回这个值。如果没有找到,NSUserDefaults就会在注册域中查找并返回默认值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值