前言:
- 在我们iOS项目中存储一些用户配置信息或者一些其他公共信息我们首先回想到用单例来做,但是单例是在app结束生命之后单例的所有属性就会消失,有得时候又不是很适合我们的需求,比如我们要记录一个登录状态或者是用户配置信息这些信息是一直存在也必须存在的,这时候我们的单例就心有余而力不足了,于是我就研究了一套单例和NSUserDefaults配合使用的案例。
实现原理:
- 首先我们实现一个单例类和一个属性Models用来存储一些属性,存储的同时我们把这个单例属性Models以NSData类型来存储到NSUserDefaults中,之后尽管app杀死单例属性消失我们的NSUserDefaults中也会把这个单例Models存储下来以便下次启动app的时候读取到单例Models中在使用。
单例的实现:
- MRC的实现我就不讲了我就直接讲下ARC单例类实现,上代码。
新建一个单例类文件(UserInfoContext)继承NSObject
UserInfoContext.h文件代码实现:
新建一个单例Models
//导入单例Modesl头文件
#import "UserInfo.h"
@property(nonatomic,strong) UserInfo *userInfo;
+(UserInfoContext*)sharedUserInfoContext;
UserInfoContext.m文件代码实现:
@synthesize userInfo;
static UserInfoContext *sharedUserInfoContext = nil;
+(UserInfoContext*)sharedUserInfoContext{
static dispatch_once_t token;
dispatch_once(&token, ^{
if(sharedUserInfoContext == nil){
sharedUserInfoContext = [[self alloc] init];
}
});
return sharedUserInfoContext;
}
+(id)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t token;
dispatch_once(&token, ^{
if(sharedUserInfoContext == nil){
sharedUserInfoContext = [super allocWithZone:zone];
}
});
return sharedUserInfoContext;
}
- (instancetype)init{
self = [super init];
if(self){
//实例化这个Models
sharedUserInfoContext.userInfo = [[UserInfo alloc] init];
}
return self;
}
- (id)copy{
return self;
}
- (id)mutableCopy{
return self;
}
新建一个单例Models(UserInfo)存放属性继承NSObject
UserInfo.h文件代码实现:
@interface UserInfo : NSObject<NSCoding>{
BOOL isLogin;//判断是否登录
NSString *phoneNumber;//手机号
NSString *cookie;//cookie
NSInteger tabBarSelected;//tabbar
NSString *deviceid;//设备号
}
@property (nonatomic,assign) BOOL isLogin;
@property (nonatomic,copy) NSString *phoneNumber;
@property (nonatomic,copy) NSString *cookie;
@property (nonatomic,assign) NSInteger tabBarSelected;
@property (nonatomic,copy) NSString *deviceid;
UserInfo.m文件代码实现(属性编码解码):
@synthesize isLogin;
@synthesize phoneNumber;
@synthesize cookie;
@synthesize tabBarSelected;
@synthesize deviceid;
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeBool:self.isLogin forKey:@"isLogin"];
[aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"];
[aCoder encodeObject:self.cookie forKey:@"cookie"];
[aCoder encodeInteger:self.tabBarSelected forKey:@"tabBarSelected"];
[aCoder encodeObject:self.deviceid forKey:@"deviceid"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self =[super init]) {
self.isLogin = [aDecoder decodeBoolForKey:@"isLogin"];
self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];
self.cookie = [aDecoder decodeObjectForKey:@"cookie"];
self.tabBarSelected = [aDecoder decodeIntegerForKey:@"tabBarSelected"];
self.deviceid = [aDecoder decodeObjectForKey:@"deviceid"];
}
return self;
}
@end
新建一个工具类(Utilities)存放属性继承NSObject
为了更好的简便的使用这个这个单例和NSUserDefaults的读取和存储
Utilities.h文件代码实现:
//单例-> NSUserDefaults
+(void)SetNSUserDefaults:(UserInfo *)userInfo;
//NSUserDefaults-> 单例
+(UserInfo *)GetNSUserDefaults;
Utilities.m文件代码实现:
//存储单例Models(UserInfo)到NSUserDefaults
+(void)SetNSUserDefaults:(UserInfo *)userInfo{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:userInfo];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:data forKey:@"user"];
[defaults synchronize];
}
//读取NSUserDefaults存储内容return到单例Modesl(UserInfo)中
+(UserInfo *)GetNSUserDefaults{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"user"];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
以上代码我们屡屡
1.开始我们实现了一个单例类(UserInfoContext);
2.在单例类中实现了一个属性Models(UserInfo);
3.实现了一个工具类方便把单例属性Models(UserInfo)存储到NSUserDefaults以及把NSUserDefaults内容读取到单例属性Models(UserInfo)中。
-
下面我们来试验调用赋值给单例Models(UserInfo)同时把单例Models(UserInfo)存储到NSUserDefaults中
//存储在单例中
UserInfo *user = [UserInfoContext sharedUserInfoContext].userInfo;
user.isLogin = YES;
user.phoneNumber = @"13552539636"
user.cookie = @"QQ396368888";
//启动app默认选中TabBar
user.tabBarSelected = 0;
//在把单例存储到NSUserDefaults(调用工具类方法)
[Utilities SetNSUserDefaults:user];
-
在AppDelegate类中得didFinishLaunchingWithOptions方法中直接读取NSUserDefaults内容到单例使用
//读取用户状态和配置信息到单例中
[UserInfoContext sharedUserInfoContext].userInfo= [Utilities GetNSUserDefaults];
-
以上我们完整的一套流程就做好了,我为什么要做这个呢,是因为我们产品提出了一个奇葩的要求就是要启动默认显示哪个TabBar和一些用户设置像App主题皮肤等等一系列要求,所以单例就不够用了。
-
代码就不上GitHub了这上面代码没有少一句照搬都可以。