在iOS开发中,数据持久化非常重要,但是新手也很迷茫,该怎么对数据进行处理呀,哪种方式好,每种方式又有什么弊端? 到底该怎么进行选择呢,接下来我想给大家分享分享,相互学习。
首先现在常用的数据持久化有4种:
XML属性列表(plist),Preference(偏好设置) ,NSkeyedArchiver(对象归档), SQlite ,CoreData
XML属性列表(plist)
适用对象:仅仅是Foundation框架中自带的一些类(NSSting,NSArray,NSData,NSNumber等等)
方法:
//1.设置路径,一般存在Document
NSString * plistfileName = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"save.plist"];
//2.设置存储内容,我以数组为例子
NSArray *writecontent=@[@"存的内容",@"存的内容" ];
//3.存入plistfileName里面
[writecontent writeToFile:plistfileName atomically:YES];
//完成
//如果以后要取出来,读取plistfileName里面
NSArray *readcontent = [NSArray arrayWithContentsOfFile:plistfileName];
NSLog(@"%@",read content);
优缺点:
plist常用于存储长时间不容易发生变化的数据,比如省市名、车辆名称等,不同类别的内容可以用不同的plist来管理。
缺点是每次都要全部加载入内存,所以不适合存大数据,而且只能存NSDate、NSNumber,NSArray等类型数据。
Preference(偏好设置)
适用对象:本质还是Plist属性列表存储方式(偏好设置类数据,比如用户密码,字体大小等)
方法:
//1.初始化userDefaults(相当于帮你自动设定好了路径以及plist名称)
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.存入内容
[userDefaults setObject:@"张三" forKey:@"name"];
[userDefaults setObject:@"1234" forKey:@"password"];
//3.立即保存(如果不写的话,它会将来某个不确定时间存入)
[userDefaults synchronize];
//完成
//如果以后要取出来, 读取userDefaults文件
NSString *name = [userDefaults objectForKey:@"name"];
NSString *password= [userDefaults objectForKey:@"password"];
NSLog(@"%@",name);
NSLog(@"%@",password);
打开com.base.data.plist
优缺点:
不用提前导入存储路径,默认就存于Library里的Preference里com.base.data.plist,通过键值对进行存取
缺点是只有一个com.base.data.plist文件来存取数据,不能分类管理,plist缓存越来越大,要读取的时候需要加载整个plist内存也吃不消,建议只存偏好设置类的小数据。
NSkeyedArchiver(对象归档)
适用对象:能将任何遵守了NScoding协议的对象塞进文件中
方法:
第一步设置协议:
#import <Foundation/Foundation.h>
@interface Student : NSObject<NSCoding>
//2.设置属性
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) NSInteger age;
@end
第二步设置对应的归档(哪些属性要存取,怎么存储)和解档(哪些属性要读取,怎么读取)
#import "Student.h"
@implementation Student
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
//解档
- (id)initWithCoder:(NSCoder *)aDecoder {
if ([super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
第三步实现
//存入student类的数据
NSString *fileName = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"stu.data"];
Student *stuWrite = [[Student alloc] init];
stuWrite.name = @"张三";
stuWrite.age = 23;
[NSKeyedArchiver archiveRootObject:stuWrite toFile:fileName];
//如果以后要取出来, 读取fileName目录下的stu.data
Student *stuRead = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
if (stuRead) {
NSString *name = stuRead.name;
NSInteger age= stuRead.age;
NSLog(@"%@",name);
NSLog(@"%ld",(long)age);
方法
优缺点:
可以存储任何遵守了协议的对象,存储后为加密的data数据。
缺点过程比较麻烦,要设置协议,要在model里面设置归档,解档。如果父类也遵守了该协议,要先调用父类的归档和解档。