IOS开发—数据存储(直接写入、NSUserDefaults、NSkeyedArchiver)
数据存储(直接写入、NSUserDefaults、NSkeyedArchiver)
ios中常用文件存取的方法有:
1、直接写文件的方式,可以存储的对象有NSString、NSArray、NSDictionary、NSData、NSNumber,数据全部存放在一个属性列表文件(*.plist文件)中。
2、NSUeserDefaults(偏好设置),用来存储应用设置信息,文件放在perference目录下。
3、归档操作(NSkeyedArchiver),不同于前面两种,它可以把自定义对象存放在文件中。
首先每个开发者都应该知道,对于一个应用来说,有唯一的沙盒与之对应,即每个应用不能跨沙盒操作文件。
一、获取沙盒路径,通过写文件的方式存储数据
直接来看代码:
#import "ViewController.h" @interface ViewController () @end @implementationViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view,typically from a nib. [self mainOperation]; } - (void)mainOperation { //获取沙盒中缓存文件夹路径 //方法一 //沙盒主目录 NSString *homePath = NSHomeDirectory(); //拼接路径 NSString *path = [homePath stringByAppendingPathComponent:@"Library/Caches"]; //方法二 //第一个参数目标文件夹目录(NSCachesDirectory查找缓存文件夹),第二个参数为查找目录的域(NSUserDomainMask为在用户目录下查找),第三个参数为结果中主目录是否展开,不展开则显示为~ NSArray *arr = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); //虽然该方法返回的是一个数组,但是由于一个目标文件夹只有一个目录,所以数组中只有一个元素。 NSString *cachePath = [arr lastObject]; //或者 // NSString *cachePath = [arr objectAtIndex:0]; /** //获取沙盒中Document文件夹或者tmp文件夹路径都可使用上面两种方法 //tmp文件夹路径可直接这样获取 NSString *tmpPath = NSTemporaryDirectory(); NSLog(@"%@",tmpPath); **/ //拼接路径(目标路径),这个时候如果目录下不存在这个lotheve.plist文件,这个目录实际上是不存在的。 NSString *filePath = [cachePath stringByAppendingPathComponent:@"tese.plist"]; NSLog(@"%@",filePath); //创建数据 NSDictionary *content = @{@"字典数据测试1":@"1",@"字典数据测试2":@"2",@"字典数据测试":@"3"}; //将数据存到目标路径的文件中(这个时候如果该路径下文件不存在将会自动创建) //用writeToFile方法写文件会覆盖掉原来的内容 [content writeToFile:filePath atomically:YES]; //读取数据(通过字典的方式读出文件中的内容) NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:filePath]; NSLog(@"%@",dic); } @end
沙盒中Library/Caches目录下多了lotheve.plist文件
文件内容:
二、使用NSUeserDefaults(偏好设置)实现数据存储
每个应用都有一个NSUesrDefaults实例,通过它可以存储应用配置信息以及用户信息,比如保存用户名、密码、字体大小、是否自动登录等等。数据自动保存在沙盒的Libarary/ Preferences目录下。同样,该方法只能存取NSString、NSArray、NSDictionary、NSData、NSNumber类型的数据。
代码示例:
#import "LXXViewController.h" @interface LXXViewController () @end @implementationLXXViewController - (void)viewDidLoad { [super viewDidLoad]; self.title = @"NSUserDefaults Demo"; } //点击button保存数据 - (IBAction)saveData:(id)sender { //获取NSUserDefaults对象 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; //存数据,不需要设置路劲,NSUserDefaults将数据保存在preferences目录下 [userDefaults setObject:@"Lotheve" forKey:@"name"]; [userDefaults setObject:@"NSUserDefaults" forKey:@"demo"]; //立刻保存(同步)数据(如果不写这句话,会在将来某个时间点自动将数据保存在preferences目录下) [userDefaults synchronize]; NSLog(@"数据已保存"); } //点击button读取数据 - (IBAction)getData:(id)sender { //获取NSUserDefaults对象 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; //读取数据 NSString *name = [userDefaults objectForKey:@"name"]; NSString *demo = [userDefaults objectForKey:@"demo"]; //打印数据 NSLog(@"name = %@ demo =%@",name,demo); } @end
Interface Building中设置了两个按钮:
点击“保存数据”后,查看沙盒中的Libarary/ Preferences目录:
数据以plist的格式写入磁盘中了。点开查看数据:
三、NSKeyedArchiver(归档操作)
使用归档操作存储数据的主要好处是,不同于前面两种方法只能存储几个常用的数据类型的数据,NSKeyedArchiver可以存储自定义的对象。
代码示例:
需要注意的是,需要保存的对象类一定要引用NSCoding协议,并且实现
- (void)encodeWithCoder:(NSCoder *)aCoder - (id)initWithCoder:(NSCoder *)aDecoder
1、文件结构:
2、代码示例:
LXXViewController.m
#import "LXXViewController.h" #import "TestPerson.h" @interface LXXViewController () @property (nonatomic ,strong) TestPerson *p; @end @implementationLXXViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)saveData:(id)sender { //创建一个自定义类的实例 _p = [[TestPerson alloc]init]; _p.name = @"Lotheve"; _p.age = 20; _p.sex = @"m"; _p.familyMumbers = @[@"Father",@"Mather",@"Me"]; //获取文件路径 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; //文件类型可以随便取,不一定要正确的格式 NSString *targetPath = [docPath stringByAppendingPathComponent:@"lotheve.plist"]; //将自定义对象保存在指定路径下 [NSKeyedArchiver archiveRootObject:_p toFile:targetPath]; NSLog(@"文件已储存"); }
- (IBAction)getData:(id)sender { //获取文件路径 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *targetPath = [docPath stringByAppendingPathComponent:@"lotheve.plist"]; TestPerson *person = [NSKeyedUnarchiver unarchiveObjectWithFile:targetPath]; NSLog(@"name = %@ , age =%ld , sex = %@ , familyMubers = %@",person.name,person.age,person.sex,person.familyMumbers); NSLog(@"文件已提取"); } @end
TestPerson.h
#import <UIKit/UIKit.h> @interface TestPerson : UIViewController<NSCoding> @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age; @property (nonatomic, copy) NSString *sex; @property (nonatomic, strong) NSArray *familyMumbers; @end
TestPerson.m
#import "TestPerson.h" @interface TestPerson () @end @implementationTestPerson - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - NSCoding协议方法 (一定要实现) //当进行归档操作的时候就会调用该方法 //在该方法中要写清楚要存储对象的哪些属性 - (void)encodeWithCoder:(NSCoder *)aCoder { NSLog(@"调用了encodeWithCoder方法"); [aCoder encodeObject:_name forKey:@"name"]; [aCoder encodeInteger:_age forKey:@"age"]; [aCoder encodeObject:_sex forKey:@"sex"]; [aCoder encodeObject:_familyMumbers forKey:@"familyMumbers"]; } //当进行解档操作的时候就会调用该方法 //在该方法中要写清楚要提取对象的哪些属性 - (id)initWithCoder:(NSCoder *)aDecoder { NSLog(@"调用了initWithCoder方法"); if (self = [super init]) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; self.sex = [aDecoder decodeObjectForKey:@"sex"]; _familyMumbers = [aDecoder decodeObjectForKey:@"familyMumbers"]; } return self; } @end
点击“保存数据”后,查看沙盒中Documents目录:
点击查看文件内容:
点击“提取数据”后打印结果:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。