iOS常用的数据持久化方案主要有四种:NSUserDefault、File、Keychain、FMDB。
NSUserDefaults
model
student.h
#import <Foundation/Foundation.h>
@interface student : NSObject <NSCoding>
@property (nonatomic, strong) NSNumber *number;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;
@end
student.m
#import "student.h"
@implementation student
- (instancetype)init
{
self = [super init];
if (self) {
// _number = @(1);
_name = @"zhiajf";
_age = @(2763);
_sex = @"男";
}
return self;
}
/*
编码器
Encodes the receiver using a given archiver(归档器).
*/
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.number forKey:@"number"];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.age forKey:@"age"];
[aCoder encodeObject:self.sex forKey:@"sex"];
}
/*
译码器
Returns an object initialized from data in a given unarchiver(取档器).
You typically return self from initWithCoder:. If you have an advanced need that requires substituting a different object after decoding, you can do so in awakeAfterUsingCoder:.
*/
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
self.number = [aDecoder decodeObjectForKey:@"number"];
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
return self;
}
@end
NSLog(@"****%@****",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]);
student *aStudent = [[student alloc] init];
aStudent.number = @1;
student *aStudent2 = [[student alloc] init];
aStudent2.number = @2;
aStudent2.name = @"第二个stu";
/*********************** NSUserDefault **********************/
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:aStudent];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"student"];
NSData *studentData = [[NSUserDefaults standardUserDefaults] objectForKey:@"student"];
student *studentModel = [NSKeyedUnarchiver unarchiveObjectWithData:studentData];
NSLog(@"****%@****",studentModel.sex);
File
/*********************** file **********************/
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingString:@"/my.archive"];
NSArray *array = @[aStudent,aStudent2];
[NSKeyedArchiver archiveRootObject:array toFile:path];
NSArray *array2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
/*
[NSKeyedArchiver archiveRootObject:aStudent toFile:path];
student *stuArchiver = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
[NSKeyedArchiver archiveRootObject:aStudent2 toFile:path];
student *stuArchiver2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
*/
student *stuArchiver = array2[0];
student *stuArchiver2 = array2[1];
// NSLog(@"****%@****",stuArchiver.name);
// NSLog(@"****%@****",stuArchiver2.name);
Keychain
/*********************** keychain **********************/
/*
参考
http://www.jianshu.com/p/9188235eedab
https://github.com/v2panda/PDKeyChain
*/
FMDB
// 创建db
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSLog(@"****%@****",path);
path = [path stringByAppendingString:@"/User.db"];
//实例化一个FMDatabase对象,并打开一个数据库,如果没有这个数据库,就会创建一个数据库
FMDatabase *db = [FMDatabase databaseWithPath:path];
// 打开db
[db open];
if(![db open]) {
return;
}
// 增删改查
/*
create\update\insert\alter\begin\detach
*/
//创建表
[db executeUpdate:@"CREATE TABLE Users(Name text,Age integer)"];
//插入数据
[db executeUpdate:@"INSERT INTO Users(Name,Age)VALUES(?,?)",@"Eric",[NSNumber numberWithInt:25]];
NSString *userName1 = [db stringForQuery:@"SELECT Name FROM Users WHERE Age = ?",@"25"];
NSLog(@"%@", userName1);
// 更新数据
[db executeUpdate:@"UPDATE Users SET Name = ? WHERE Name = ?",@"Michael",@"Eric"];
NSLog(@"%@", userName1);
//删除数据
[db executeUpdate:@"DELETE FROM Users WHERE Name = ?",@"Michael"];
//查询数据
NSString *userName = [db stringForQuery:@"SELECT Name FROM Users WHERE Age = ?",@"25"];
NSLog(@"%@", userName);
//查询多个数据,FMResultSet类,是一个结果集,返回多条数据,FMDB会将数据放在这个结果集中,然后在对这个结果集进行查询即可
FMResultSet *res = [db executeQuery:@"SELECT * FROM Users"];
res = [db executeQuery:@"SELECT * FROM Users WHERE Age = ?",@"25"];
while ([res next]) {
NSString *name = [res stringForColumn:@"Name"];
NSString *age = [res stringForColumn:@"Age"];
NSLog(@"%@%@", name, age);
}
// 关闭db
[db close];
// 使用FMDatabaseQueue类实现多线程操作
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:fileName];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"create table if not exists t_student_q (id integer primary key autoincrement, name text not null, age integer not null)"];
int age = 42;
NSString *name = @"name 1";
//1.executeUpdate:不确定的参数用?来占位(后面参数必须是oc对象,;代表语句结束)
[db executeUpdate:@"INSERT INTO t_student_q (name, age) VALUES (?,?);",name,@(age)];
FMResultSet *rs = [db executeQuery:@"select * from t_student_q"];
while([rs next]) {
NSString *name = [rs objectForColumnName:@"name"];
NSLog(@"****%@==****",name);
}
}];
参考
FMDB
FMDB多线程安全问题
网友评论