概论
数据持久化存储:所谓持久化存储就是将数据保存到硬盘中,使得应用程序或者机器在重启后可以访问之前保存的数据。
常见方式:
沙盒
说到持久化存储就不得不说一下苹果的沙盒机制,苹果的一个应用程序就对应一个沙盒。
这样做的好处有以下几点:
那怎么打开沙盒呢?
进入沙盒之后我们能看到三个文件夹:
*Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
*Preferences:偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。
iTunes在与iPhone同步时,备份所有的Documents和Library文件。
iPhone在重启时,会丢弃所有的tmp文件。
那我们怎么在程序中得到这些路径呢?
Document:
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSLog(@"%@", documentPath);
Library/Caches:
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; NSLog(@"%@", cachePath);
tmp:
NSString *tmpPath = NSTemporaryDirectory(); NSLog(@"%@", tmpPath);
plist文件
plist就是将某些特定的类,通过XML方式保存在目录中。
可以被序列化的类型只有以下几种:(其中根结点必须是NSArray或者NSDictionary)
NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumber;
NSDate;
BOOL
//获取文件路径 NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *fileName = [documentPath stringByAppendingPathComponent:@"file.plist"]; //存储 NSArray *array = @[@{@"字典":@"dict"}, @YES, @"string", @(10), ]; [array writeToFile:fileName atomically:YES]; //读取 NSArray *resultArray = [NSArray arrayWithContentsOfFile:fileName]; NSLog(@"%@",resultArray);
Preference:偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。
//1.获得NSUserDefaults文件 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; //2.向文件中写入内容 [userDefaults setObject:@"wuhongxing" forKey:@"name"]; [userDefaults setBool:YES forKey:@"sex"]; [userDefaults setInteger:21 forKey:@"age"]; //2.1立即同步 [userDefaults synchronize]; //3.读取文件 NSString *name = [userDefaults objectForKey:@"name"]; BOOL sex = [userDefaults boolForKey:@"sex"]; NSInteger age = [userDefaults integerForKey:@"age"]; NSLog(@"%@, %d, %ld", name, sex, age);
NSKeyedArchiver:归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化
1.遵循NSCoding协议
@interface Person : NSObject <NSCoding> /**名字*/ @property (nonatomic, copy) NSString *name; /**年龄*/ @property (nonatomic, assign) NSInteger age; /**头像*/ @property (nonatomic, strong) UIImage *avatar; @end
2.实现NSCoding协议
//归档 - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_avatar forKey:@"avatar"]; [aCoder encodeObject:_name forKey:@"name"]; [aCoder encodeInteger:_age forKey:@"age"]; } //解档 - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { self.avatar = [aDecoder decodeObjectForKey:@"avatar"]; self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; } return self; }
特别注意:如果归档的类是某个自定义类的子类,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
3.使用
//需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。 NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"]; Person *per = [[Person alloc] init]; per.name = @"whx"; per.age = 24; per.avatar = UIImagePNGRepresentation([UIImage imageNamed:@"tab_accountH"]); [NSKeyedArchiver archiveRootObject:per toFile:documentPath]; //需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。 Person *resultPer = [NSKeyedUnarchiver unarchiveObjectWithFile:documentPath]; if (resultPer) { NSLog(@"%@ %li %@",resultPer.name,resultPer.age,[UIImage imageWithData:per.avatar]); }
SQLite3:之前的所有存储方法,都是覆盖存储。如果想要增加一条数据就必须把整个文件读出来,然后修改数据后再把整个内容覆盖写入文件。所以它们都不适合存储大量的内容。
1.字段类型
表面上SQLite将数据分为以下几种类型:
integer : 整数
real : 实数(浮点数)
text : 文本字符串
blob : 二进制数据,比如文件,图片之类的
实际上SQLite是无类型的。即不管你在创表时指定的字段类型是什么,存储是依然可以存储任意类型的数据。而且在创表时也可以不指定字段类型。SQLite之所以什么类型就是为了良好的编程规范和方便开发人员交流,所以平时在使用时最好设置正确的字段类型!主键必须设置成integer
2. 准备工作
准备工作就是导入依赖库啦,在iOS中要使用SQLite3,需要添加库文件:libsqlite3.dylib并导入主头文件,这是一个C语言的库,所以直接使用SQLite3还是比较麻烦的。
3.如何使用:数据库涉及到的常见操作有增、删、改、查。
基于FMDB的再封装
1.简介
FMDB是iOS平台的SQLite数据库框架,它是以OC的方式封装了SQLite的C语言API,它相对于cocoa自带的C语言框架有如下的优点:
使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
对比苹果自带的Core Data框架,更加轻量级和灵活
提供了多线程安全的数据库操作方法,有效地防止数据混乱
2.核心类
FMDB有三个主要的类:
FMDatabase
一个FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句
FMResultSet
使用FMDatabase执行查询后的结果集
FMDatabaseQueue
用于在多线程中执行多个查询或更新,它是线程安全的
3.使用:等我写关于数据库的时候详细说。