NSUserDefaults类,以字典形式保存数据,IOS会自动把字典中的键值对转换成对应的XML文件(也就是plist文件),这个文件会被保存到APP的沙盒目录中(路径为Library/Preferences/plist文件名)。
NSUserDefaults为我们封装了读写plist文件的常用操作,我们可以使用它来保存一些简单的数据,比如系统配置,用户设置的参数之类的。
获取当前沙盒的Documents路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
查看当前沙盒文件
A文件内容
说明:上图中A(Bundle identifier.plist)是系统自动为我们创建的plist文件用来保存我们使用NSUserDefaults保存的数据。B为我们自己创建的的 plist文件,默认是在 Documents下。
Attempt to insert non-property list object 报错原因,
简便方法存取不同类型数据 由上边的例子可以看到一个方法-setInteger:,这跟常用的-setObject:相比设置类型更明确。其实,NSUserDefaults提供了若干简便方法可以存储某些常用类型的值,例如:
- setBool:forKey:
- setFloat:forKey:
- setInteger:forKey:
- setDouble:forKey:
- setURL:forKey:
这将使某些值的设置更简单。
NSUserDefaults 常规使用方法封装
- (void)setUserDefaults :(id)obj :(NSString*)key;
{
if (!obj) {
return;
}
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
[[NSUserDefaults standardUserDefaults] setObject:obj forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (id)getUserDefaults :(NSString*)key;
{
return [[NSUserDefaults standardUserDefaults]objectForKey:key];
}
- (void)removeOneDefaults :(NSString *)key;
{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
打印出系统中所有的 NSUserDefaults设置
NSDictionary* defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
NSLog(@"Defaults: %@", defaults);
- (void)registerDefaults:方法来初始化,这个方法会检查 NSUserDefaults是否已经存在了相同的key,如果存在就不会将其覆盖(相当于什么也没做),如果不存在就做保存操作。
简单举例来说明一下:
1.当第一次运行app时初始化了@"color":@"blue"
[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"color":@"blue"}];
这时NSUserDefaults里面'color'=='blue';
2.如果你在app中又重新设置了'color'=='red';
3.这时你重新运行一下你的app,仍然会调用[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"color":@"blue"}];;但是此时,它检测到color这个key已经存在,并且'color'=='red',
就不将blue写入NSUserDefaults中。此时依然是'color'=='red';
使用归档存储(真的储存)
一个NSUserDefaults的对象必须是属性表,这也就是说我们可以存储NSData,NSString,NSNUmber,NSDate,NSArray,NSDictionary这些实例。如果你想存储其他类型的对象,我们可以将其归档并创建一个NSData来实现存储。
让这个自定义类实现<NSCoding>协议中的 - (id) initWithCoder: (NSCoder *)coder方法和 - (void) encodeWithCoder: (NSCoder *)coder方法 然后把该自定义的类对象编码到NSData中,再从NSUserDefaults中进行读取。
#import <Foundation/Foundation.h>
@interface Test : NSObject
<NSCoding>
@property(copy,nonatomic)NSString *imageName;
@property(copy,nonatomic)NSString *ageStr;
@end
#import "Test.h"
@implementation Test
- (id) initWithCoder: (NSCoder *)coder
{
if (self = [super init])
{
self.imageName = [coder decodeObjectForKey:@"imageName"];
self.ageStr = [coder decodeObjectForKey:@"ageStr"];
}
return self;
}
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:self.imageName forKey:@"imageName"];
[coder encodeObject:self.ageStr forKey:@"ageStr"];
}
@end
使用NSUserDefaults 储存
Test *bc = [[Test alloc] init];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSData *udObject = [NSKeyedArchiver archivedDataWithRootObject:bc];
[ud setObject:udObject forKey:@"myBusinessCard"];
udObject = [ud objectForKey:@"myBusinessCard"];
bc = [NSKeyedUnarchiver unarchiveObjectWithData:udObject];
储存 NSDictionary 后赋值给对象(假储存)
- (void)saveSchoolInfo:(NSDictionary *)info {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:info forKey:@"school"];
[userDefaults synchronize];
}
- (School *)getSchool {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *info = [userDefaults objectForKey:@"school"];
School *school = [School objectWithKeyValues:info];
return school;
}
值得注意的是,存入的NSDictionary里面必须不能包含 Null 对象,否则就会抛出异常
写入文件方法:writeToFiel:对象调用方法
- (void)writeDataToPlist :(NSString *)dataKey :(id)data
{
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *path=[paths objectAtIndex:0];
NSLog(@"path:%@",path);
NSString *filename=[path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",dataKey]];
//写入
NSFileManager* fm = [NSFileManager defaultManager];
[fm createFileAtPath:filename contents:nil attributes:nil];
[data writeToFile:filename atomically:YES];
if ([fm fileExistsAtPath:filename]) {
NSLog(@"%@",[NSString stringWithFormat:@"%@文件写入成功",dataKey]);
}
}
返回的是文件的路径
- (NSString *)getDataFormPlist :(NSString *)dataKey
{
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *path=[paths objectAtIndex:0];
NSString *filename=[path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",dataKey]];
return filename;
}
读取文件:每个类自带的能够根据文件路径读取文件的方法:[类名 + WithContentOfFiel],如下: WithOfContentFiel 后面跟的是文件的路径
NSString :[NSString StringWithContentOfFile:]
NSArry :[NSArry arrayWithContentOfFiel:]
NSDictionary :[NSDictionary dictionaryWithOfContentFile:]
二进制流 :[NSData dataWithOfContentFiel:]
NSUserDefaults的使用是比较简单的,本文旨在从总体上了解NSUserDefaults的本质和使用方法。