数据持久化有四种方式
属性列表文件和对象归档一般用于存储少量数据。属性列表文件的访问要比对象归档的访问简单,Foundation框架集合对象都有对应的方法读写属性列表文件,对象归档是用NSData实现的。SQLite数据库和Core Data一般用于有几个简单表关系的大量数据的存储。
// 存
[[NSUserDefaults standardUserDefaults] setInteger:userID forKey:@”userID”];
[[NSUserDefaults standardUserDefaults] setObject:name forKey:@”name”];
// 取
NSInteger uId = [[[NSUserDefaults standardUserDefaults] integerValueForKey:@”userID”];
NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey:@”name”];
对象归档是一种序列化。为了便于数据的传输,先将归档对象序列化成文件,然后再通过反归档将数据恢复到对象中。归档技术可以实现数据的持久化,这种方式不适合大量数据和频繁读写的情况。
对一个对象进行完整归档必须满足一定的条件:对象类必须实现NSCoding协议,而且每个成员变量应该是基本数据类型或都是实现了NSCoding协议的某个类实例。
NSData提供了一些读写文件的方法,因此归档和反归档总是与NSData关联在一起使用。
归档过程是使用NSKeyedArchiver对象归档数据,具体过程为:先将归档数据写入NSData对象,然后在将NSData对象写入归档文件中。
反归档过程是从归档文件中读取数据到NSData对象,再利用NSKeyedUnarchiver对象从NSData对象中反归档出数据。
要使用对象归档,对象必须实现NSCoding协议.大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,实现两个方法:
- (void) encodeWithCoder:(NSCoder *)encoder
-(void)initWithCoder:(NSCoder *)encoder
同时,建议对象也同时实现NSCopying协议,该协议允许复制对象,要实现NSCopying协议须实现 -(id)copyWithZone:(NSZone *)zone 方法 。
@interface User : NSObject <NSCoding>
@property (nonatomic, assign) NSInteger userID;
@property (nonatomic, copy) NSString *name;
@end
@implementation User
// 以下两个方法一定要实现,不然在调用的时候会crash
- (void)encodeWithCoder:(NSCoder *)aCoder;
{
// 这里放置需要持久化的属性
[aCoder encodeObject:[NSNumber numberWithInteger:self.userID] forKey:@”userID”];
[aCoder encodeObject:self.name forKey:@"name"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [self init])
{
// 这里务必和encodeWithCoder方法里面的内容一致,不然会读不到数据
self.userID = [[aDecoder decodeObjectForKey:@"userID"] integerValue];
self.name = [aDecoder decodeObjectForKey:@"name"];
}
return self;
}
// 使用方法
+ (BOOL)save {
NSError *error = nil;
// 确定存储路径,一般是Document目录下的文件
NSString* fileName = [self getFileName];
NSString* filePath = [self getFilePath];
if (![[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error]) {
NSLog(@”创建用户文件目录失败”);
return NO;
}
return [NSKeyedArchiver archiveRootObject:self toFile:[fileName:userId]];
}
@end
SQLite是嵌入式系统中使用的关系数据库,目前主流版本是SQLite 3。SQLite运行时与使用它的应用程序之间共用相同的进程空间,而不是单独的两个进程。
SQLite提供了对SQL-92标准的支持,支持多表、索引、事物、视图和触发。SQLite是无数据类型的数据库,就是字段不用指定类型。
虽然SQLite可以忽略数据类型,但从编码规范上讲,应该在建表语句中指定数据类型,这样便于代码的阅读和理解。SQLite支持的常见数据类型如下:
INTEGER,有符号的整数类型。
REAL,浮点类型。
TEXT,字符串类型,采用UTF-8和UTF-16字符编码。
BLOB,二进制大对象类型,能够存放任何二进制数据。
SQLite提供的API比较多,文档对SQLite的用法以及一些API描述得很详细,实际使用过程中我们可以查阅文档。比如,在创建数据库时,我们需要经过如下3个步骤:
(1)使用sqlite3_open打开数据库;
(2)使用sqlite3_exec执行Create Table语句,创建数据表;
(3)使用sqlite3_close释放资源。
这些都是SQLite提供的C语言API,在OC中使用时需要注意数据类型的兼容问题。
其他像查询、删除等过程的调用,文档上都有详细的说明,这里就不赘述了。
这里还有一点需要注意,在使用SQLite之前,我们需要在工程中添加SQLite 3的库libsql3.dylib或libsql3.0.dylib。
core Data是一种ORM(对象关系映射。ORM是关系模型数据和对象模型类之间的一个纽带)技术。Core Data是Apple为Mac OS X和iOS系统应用开发提供的数据持久化技术。它基于高级数据持久化API,它的底层最终是SQLite、二进制文件和内存数据保存,这样应用开发层面不用关心数据的存储细节,不用再使用SQL语句,也不用面对SQLite的C语言函数。