介绍:NSUserDefaults适合存储轻量级的本地数据,一些简单的数据(NSString类型的)例如密码,网址等。如果要使用NSUserDefaults存储自定义的对象还需要进行特定的处理。
一、NSUserDefaults是一个单例,在整个程序中只有一个实例对象,它可以用于简单数据的保存,而且简单实用,这是它可以让数据自由传递的前提。 使用NSuserDefaults可以直接存储的数据类型如下所示:
NSUserDefaults 支持的数据类型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL
如果想要将上述数据类型的数据永久保存到NSUserDefaults中去,只需要简单的操作(一个Value 一个Key ),例如,想要保存一个NSString的对象,代码实现为:
//将NSString 对象存储到 NSUserDefaults 中 NSString *passWord = @"1234567"; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:passWord forKey:@"userPassWord"];将数据取出也很简单,只需要取出key对应的值即可,代码如下:
NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSString *passWord = [ user objectForKey:@"userPassWord"];
注意:
(一)对相同的键即key赋值等于一次覆盖,要保证每一个key的唯一性
也可以利用这一特征来根据不同操作产生不同的判别标志进行覆盖。
(二) NSUserDefaults存储的对象必须全部是不可变的(假设存储的是数组,但是大小不确定要用NSMutableArray存储但存储完毕后一定要转换成NSArray类型才可以存放到NSUserDefaults中)
(三) NSUserDefaults不支持直接存储自定义对象,但是它支持存储NSData对象,只有把遵守NScoding协议并实现编码解码方法的对象转化为NSdata才可以存储到NSUserDefaults中。
(四)如果要在NSUserDefaults中存放多个自定义对象的话,就遍历对象数组分别转化为NSdata类型对象存到data数组中,再将存放多个NSdata对象的数组存到NSUserDefault。
二 、利用NSuserDefault存储自定义对象
因为NSFileManager很麻烦要亲自创建路径和文件等等,而NSUserDefaults直接就存到本地沙盒了,而且是单例模式同一程序的任意文件随意访问,非常方便
1、将自定义对象转化为NSdata类型
<1> 让要存储的对象所在的类遵守NScoding协议并添加编码和解码方法
<2> 使用NSKeyedArchiver类的类方法archivedDataWithRootObject: 将对象转为NSData类型,例如:
<3> 如果要存放多个对象信息
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:data forKey:@"oneStudent"];
// 如果你只想存一个人的信息,你可以直接将NSData存入NSUserDefaults中 : NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:data forKey:@"oneStudent"]; //如果你想存储全班同学的信息,你还要用一个for循环将data 放入 dataArray中,这里具体的操作就不实现了,只给出存放的代码: //记住要转换成不可变数组类型 NSArray * array = [NSArray arrayWithArray:dataArray]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:array forKey:@"allStudent"]; 从NSUserDefaults中取出数据在还原也很简单 // 例如还原一个学生的数据: NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSdData *data = [user objectForKey:@"oneStudent"]; Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data]; //总之,NSUserDefaults 在我们编写代码中是最常用的一个永久保存数据的方法,也是最简单的。
网络获取json串如下:
一个大字典包含了一个小字典——需要新建一个类包含另一个类的对象作为成员(新建两个组合关系的类)
新建UserForm类, 即被包含类
UserForm.h
// // UserForm.h // 创业项目工程 // // Created by apple on 15/9/23. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import <Foundation/Foundation.h> @interface UserForm : NSObject <NSCoding> @property (nonatomic, strong) NSString * name; @property (nonatomic, assign) double balance; @property (nonatomic, assign) int option; @property (nonatomic, assign) int income; @property (nonatomic, strong) NSString *typeName; @property (nonatomic, strong) NSString *typeId; -(instancetype) initWithDict:(NSDictionary *) dict; +(instancetype) userWithDict:(NSDictionary *)dict; @endUserForm.m
// // UserForm.m // 创业项目工程 // // Created by apple on 15/9/23. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import "UserForm.h" @implementation UserForm -(instancetype) initWithDict:(NSDictionary *) dict { if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype) userWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; } -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:[NSNumber numberWithDouble:self.balance] forKey:@"balance"]; [aCoder encodeObject:[NSNumber numberWithInt:self.option] forKey:@"option"]; [aCoder encodeObject:[NSNumber numberWithInt:self.income] forKey:@"income"]; [aCoder encodeObject:self.typeName forKey:@"typeName"]; [aCoder encodeObject:self.typeId forKey:@"typeId"]; } -(id) initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.balance = [[aDecoder decodeObjectForKey:@"balance"] doubleValue]; self.option = [[aDecoder decodeObjectForKey:@"option"] intValue]; self.income = [[aDecoder decodeObjectForKey:@"income"] intValue]; self.typeName = [aDecoder decodeObjectForKey:@"typeName"]; self.typeId = [aDecoder decodeObjectForKey:@"typeId"]; } return self; } -(NSString *)description { NSString *t = [NSString stringWithFormat:@"name= %@\tbalance=%lf\n option= %d\tincome= %d\n typename=%@\ttypeId=%@" ,self.name,self.balance,self.option,self.income,self.typeName,self.typeId ]; return t; } @end
UserModel.h
// // UserModel.h // 创业项目工程 // // Created by apple on 15/9/23. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import <Foundation/Foundation.h> @class UserForm; @interface UserModel : NSObject<NSCoding> @property(nonatomic, assign) int error; @property (nonatomic, strong) NSString * message; @property (nonatomic, strong) UserForm * list; -(instancetype) initWithDict:(NSDictionary *) dict; +(instancetype) userWithDict:(NSDictionary *) dict; @end
UserModel.m
// // UserModel.m // 创业项目工程 // // Created by apple on 15/9/23. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import "UserModel.h" @implementation UserModel -(instancetype) initWithDict:(NSDictionary *) dict { if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; NSDictionary *formDict = [dict objectForKey:@"list"]; self.list = [UserForm userWithDict:formDict]; } return self; } +(instancetype) userWithDict:(NSDictionary *) dict { return [[self alloc] initWithDict:dict]; } -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:[NSNumber numberWithInt:self.error] forKey:@"error"]; [aCoder encodeObject:self.message forKey:@"message"]; [aCoder encodeObject:self.list forKey:@"list"]; } -(NSString*)description { NSString *t= [NSString stringWithFormat:@"error= %d\tmessage= %@\nlist=\n%@",self.error, self.message,self.list]; return t; } -(id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { self.error = [[aDecoder decodeObjectForKey:@"error"] intValue]; self.message = [aDecoder decodeObjectForKey:@"message"]; self.list = [aDecoder decodeObjectForKey:@"list"]; } return self; } @endmodel类的建立完成并实现了编码解码方法:
在程序中的一个登陆页存放一个Model 代码如下:
UserModel *use = [UserModel userWithDict:dict]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:use]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:data forKey:@"user"];然后登陆后在任意.m文件内就可以访问到用户信息 获取Model时代码如下:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [defaults objectForKey:@"user"];
注意:在对类进行编码解码时要注意组合和继承两种情况
(一)所有要写入文件的类都要实现编码和解码
(二)对于组合而言,直接把对象成员当成一个普通的对象即可 setObject: forKey:
(三)对于继承而言如下:
如果父类也遵守了NSCoding协议,请注意:
应该在encodeWithCoder:方法中加上一句
[super encodeWithCode:encode];
继承的实例变量也能被编码,即也能被归档
应该在initWithCoder:方法中加上一句
self = [super initWithCoder:decoder];
确保继承的实例变量也能被解码,即也能被恢复