iOS 数据存储
数据存储
一、iOS常用的有5种数据存储方式:
1、plist文件存储:(缺点:只能存储含有 writeToFile:方法的对象,如NSDictionary,NSArray等.)
/** 保存数据*/
- (void)saveData
{
//1.获取沙盒根路径
NSString *homePath = NSHomeDirectory();
//2.document路径
NSString *path = [homePath stringByAppendingPathComponent:@"Documents"];
//3.新建数据
NSArray *array = [NSArray arrayWithObjects:@"nan",@(22), nil];
NSDictionary *dict = @{@"sss":@"sddd",@"ssssaw":@(1222)};
//4.存储数据
NSString *fullPath1 = [path stringByAppendingPathComponent:@"data1.plist"];
NSString *fullPath2 = [path stringByAppendingPathComponent:@"data2.plist"];
//数组写入plist
[array writeToFile:fullPath1 atomically:YES];
//字典写入plist
[dict writeToFile:fullPath2 atomically:YES];
NSLog(@"dict - %@",dict);
}
/** 读取数据*/
- (void)readData {
//1.获取home目录
NSString *home = NSHomeDirectory();
//2.拼接Document目录
NSString *path = [home stringByAppendingPathComponent:@"Documents"];
//3.文件路径
NSString *filePath1 = [path stringByAppendingPathComponent:@"data1.plist"];
NSString *filePath2 = [path stringByAppendingPathComponent:@"data2.plist"];
//4.读取文件
NSArray *array = [NSArray arrayWithContentsOfFile:filePath1];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath2];
NSLog(@"array - %@, dict - %@",array , dict);
}
2、NSUserDefaults:(缺点:本质还是plist文件存储,相对于plist文件存储来讲存储数据更快捷。)
/** 保存数据*/
- (void)saveUserDefaults{
// 1.利用NSUserDefaults,就能直接访问软件的偏好设置(Library/Preferences)是个单例对象
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//2.存储数据
[defaults setObject:@"sd" forKey:@"user"];
[defaults setObject:@"123w" forKey:@"test"];
[defaults setInteger:20 forKey:@"age"];
[defaults setBool:YES forKey:@"auto_login"];
[defaults synchronize]; //3.立刻同步(相当于更新数据)
}
/** 读取数据*/
- (void)readUserDefaults{
//1.建立NSUserDefaults对象
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//2.读取数据
NSString *user = [defaults objectForKey:@"user"];
NSString *test = [defaults objectForKey:@"test"];
NSInteger age = [defaults integerForKey:@"age"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
NSLog(@"user =%@\n test=%@\n age =%ld\n autoLogin =%d\n",user,test,age,autoLogin);
}
注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入[defaults synchornize];UserDefaults存放目录 Library/Preference。用来保存应用程序设置和属性、用户保存的数据,用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、 NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。
3、NSKeyedArchiver(NSCoding):(归档的形式来保存数据,只能一次性归档保存以及一次性解压。所以只能针对小量数据,而且对数据操作比较笨拙,即如果想改动数据的某一小部分,还是需要解压整个数据或者归档整个数据。)
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
@property (nonatomic , copy) NSString *name;
@property (nonatomic , assign) int age;
@property (nonatomic , assign) double height;
@end
#import "Person.h"
@implementation Person
- (void)encodeWithCoder:(NSCoder *)enCoder
{
NSLog(@"enCoder - %@",enCoder);
[enCoder encodeObject:self.name forKey:@"name"];
[enCoder encodeInt:self.age forKey:@"age"];
[enCoder encodeDouble:self.height forKey:@"height"];
}
/**哪些属性要解档*/
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
//读取文件内容
self.name = [decoder decodeObjectForKey:@"name"];
self.age = [decoder decodeIntForKey:@"age"];
self.height = [decoder decodeDoubleForKey:@"height"];
}
return self;
}
@end
/******归档解档*******/
- (void)saveCoder{
//1.数据对象
Person *p1 = [[Person alloc] init];
p1.name = @"张三";
p1.age = 20;
p1.height = 1.98;
//2.归档数据对象
//2.1获得文件的Documents全路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
//2.2获得文件的全路径
NSString *path = [doc stringByAppendingPathComponent:@"person.txt"];
//2.3将对象归档
[NSKeyedArchiver archiveRootObject:p1 toFile:path];
}
- (void)readCoder{
// 1.获得Documents的全路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 2.获得文件的全路径
NSString *path = [doc stringByAppendingPathComponent:@"person.txt"];
// 3.从文件中读取Person对象
Person *p3 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@ %d %f", p3.name, p3.age, p3.height);
}
注意:如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复,不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以NSCoding协议有2个方法:encodeWithCoder:每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量;initWithCoder:每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量。如果父类也遵守了NSCoding协议,应该在encodeWithCoder:方法中加上一句[super encodeWithCode:encode];确保继承的实例变量也能被编码, 也能被归档;应该在initWithCoder:方法中加上一句self = [super initWithCoder:decoder];确保继承的实例变量也能被解码,即也能被恢复; 但有时候可能想将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象,NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。
4、文件保存,write写入磁盘:()
- 第一步:获取文件保存路径
方法一:NSArray*documentPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
方法二:NSString *sandboxPath = NSHomeDirectory();NSString *documentPath = [sandboxPath stringByAppendingPathComponent:@“Documents"];
区别:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因为该文件目录可能在未来发送的系统上发生改变。
- 第二步:生成在该路径下的文件
NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件名
- 第三步:往文件中写入数据
[datawriteToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName
- 最后一步:从文件中读出数据
NSDatadata=[NSDatadataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据
5.SQLite3(SQLite3是一款开源的嵌入式关系型数据库,可移植性好、易使用、内存开销小.SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中。)
SqLite3开发中一般使用第三方框架FMDB,FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API。
FMDB的优点:
- 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码。
- 对比苹果自带的Core Data框架,更加轻量级和灵活。
- 提供了多线程安全的数据库操作方法,有效地防止数据混乱
二、应用沙盒的文件目录包含的文件类型:
- Document:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。
- temp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。
- Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据。
- Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录。

浙公网安备 33010602011771号