iOS-4种为主存储格局

应用程序的文件目录

�应用文件目录

  • Document
    :保存应用运行时生成的急需持久化的数量,iTunes同步设备时会备份该目录。例如,游戏选拔可将游乐存档保存在该目录

  • Library/Caches
    :保存应用运行时生成的急需持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不必要备份的非紧要数据

  • Library/Preference:
    保存应用的保有偏好设置,iOS的Settings(设置)应用会在该目录中找找应用的安装音信。iTunes同步设备时会备份该目录

  • temp
    :保存应用运行时所需的临时数据,使用达成后再将相应的文书从该目录删除。应用尚未运行时,系统也恐怕会免去该目录下的公文。iTunes同步设备时不会备份该目录

注: initWithCoder几时必要调用[super initWithCoder:]
• initWithCoder原理:只要解析文件就会调用,xib,storyboard都是文件,因此只要解析这两个文件,就会调用initWithCoder。
• 因此如果在storyboard使用自定义view,重写initWithCoder方法,一定要调用[super initWithCoder:],因为只有系统才知道怎么解析storyboard,如果没有调用,就解析不了这个文件。

存储方式介绍

  1. NSKeyedArchiver: 选取归档的款型来保存数据沙盒中;
  2. NSUserDefaults:偏好设置数据存到沙盒的Library/Preferences目录(本质是plist);
  3. Write写入措施: 永久保存在磁盘中;
  4. SQLite :采纳SQLite数据库来囤积数据。

在iOS开发过程中,不管是做怎样应用,都会碰着数据保存的问题。本地存储对增强多少交互成效具有重大的意思。本文总括一下数目存储的三种方法

2.NSUserDefaults:(偏好设置,本质是plist)

用来保存应用程序设置和总体性、用户保存的数量。用户再度打开程序或开机后那么些数量仍然存在。
NSUserDefaults可以储存的数据类型包罗:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。若是要存储其余品种,则需要转移为眼前的品种,才能用NSUserDefaults存储。

  • 好处:1.不必要关心文件名
    2.飞速做键值对存储

  • 坏处: 能及时存储,必要做同步操作,把内存中的数目同步到硬盘上

  • 底层:就是包装了一个字典

总结:

为了幸免同步过程时间过长,你必要对应用中运用的文书放在何地做出抉择。很大的数据文件,尽量停放在Caches目录下,而不是Documents目录下,Documents目录下文件将做备份,那样会很耗时。


注:在iOS7在此之前,默许不会即时跟硬盘同步

存储:

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    [userDefaults setObject:@"DNS" forKey:@"name"];
    // 在iOS7之前,默认不会马上把跟硬盘同步
    // 同步操作
    [userDefaults synchronize];

读取:

    NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"];
    NSLog(@"%@",name);
二、核心类

FMDB有八个重点的类

  1. FMDatabase
    一个FMDatabase对象就代表一个独立的SQLite数据库
    用来施行SQL语句

  2. FMResultSet
    利用FMDatabase执行查询后的结果集

  3. FMDatabaseQueue
    用来在三十二线程中执行多少个查询或更新,它是线程安全的

使用FMDatabaseQueue

线程安全:在两个线程中并且选用一个FMDatabase实例是不明智的。现在您可以为每个线程成立一个FMDatabase对象。
不要让七个线程分享同一个实例,它不可能在多少个线程中而且利用。
若此,程序会时不时崩溃,或者报告丰富,令人倾家荡产。所以,不要起初化FMDatabase对象,然后在四个线程中采纳。

请使用 FMDatabaseQueue。以下是运用办法:

//首先创建队列。
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
//这样使用。
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];

while([rs next]) { … }}];
//像这样,轻松地把简单任务包装到事务里:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];

if (whoopsSomethingWrongHappened) { *rollback = YES; return; }

// etc… [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];

FMDatabaseQueue 后台会建立系列化的G-C-D队列,并执行你传给G-C-D队列的块。这意味着 你从多线程同时调用调用方法,GDC也会按它接收的块的顺序来执行。
缺点:

归档的样式来保存数据,只可以四回性归档保存以及一遍性解压。所以不得不针对小量数据,而且对数码操作比较粗笨,即只要想更改数据的某一小部分,依旧要求解压整个数据或者归档整个数据。
譬如说对Person对象归档保存。
定义Person:

@interface Person:NSObject{//遵守NSCoding协议
 NSString *name;//待归档类型
}
@implementation Person
-(void)encodeWithCoder:(NSCoder *)aCoder
{
 [aCoder encodeObject:name forKey:@"name"];
}
-(void)initWithCoder:(NSCoder *)aDecoder
{
 name=[aDeCoder decodeObjectforKey:@"name"];
}

归档操作:
一旦对Person对象name属性归档保存,只需求NSCoder子类NSKeyedArchiver的措施archiveRootObject:toFile:
即可。

    // 创建person对象
    Person *person = [[Person alloc] init];
    person.name = @"DNS";
    // 获取cache
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    // 拼接文件全路径
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"person.data"];
    // 把自定义对象归档
    [NSKeyedArchiver archiveRootObject:person toFile:filePath];

解档操作:
无异于调用NSCoder子类NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可

    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"person.data"];
    // 解档
    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

3. Write写入措施:永久保存在磁盘中。

具体方法为:
先是步:获得文件即将保存的门道:

//使用C函数NSSearchPathForDirectoriesInDomains来获得沙盒中目录的全路径。
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
//该函数有三个参数,目录类型、he domain mask、布尔值。
//其中布尔值表示是否需要通过~扩展路径。而且第一个参数是不变的,即为NSSearchPathDirectory 。
//在IOS中后两个参数也是不变的,即为:NSUserDomainMask 和 YES。
NSString *ourDocumentPath =[documentPaths objectAtIndex:0];


//还有一种方法是使用NSHomeDirectory函数获得sandbox的路径。
NSString *sandboxPath = NSHomeDirectory();
//将Documents添加到sandbox路径上
NSString *documentPath = [sandboxPath stringByAppendingPathComponent:@"Documents"];


//这两者的区别就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因为该文件目录可能在未来发送的系统上发生改变。

其次步:生成在该路线下的文本:

//fileName就是保存文件的文件名
NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];

其三步:往文件中写入数据:

//将NSData类型对象data写入文件,文件名为FileName
[data writeToFile:FileName atomically:YES];
//最后从文件中读出数据:
NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];
四、执行更新

在FMDB中,除查询以外的享有操作,都叫作“更新”
create、drop、insert、update、delete等

使用executeUpdate:方法执行更新
- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments

示例
[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]

4. SQLite:选拔数据库来储存数据。

SQLite
(http://www.sqlite.org/docs.html)
是一个轻量级的关周详据库。iOS
SDK很已经援救了SQLite,在选择时,只须求参加 libsqlite3.dylib
看重以及引入 sqlite3.h 头文件即可。不过,原生的SQLite
API在行使上一定不友好,在动用时,极度不方便。于是,开源社区中就应运而生了一雨后春笋将SQLite
API进行打包的库,而FMDB
(https://github.com/ccgus/fmdb)
则是开源社区中的优异者。

  1. 什么是FMDB
    FMDB是iOS平台的SQLite数据库框架
    FMDB以OC的形式封装了SQLite的C语言API

  2. FMDB的优点
    使用起来尤其面向对象,省去了过多劳动、冗余的C语言代码
    比较苹果自带的Core Data框架,尤其轻量级和灵活
    提供了八线程安全的数据库操作方法,有效地防止数据错乱

  3. FMDB的github地址
    https://github.com/ccgus/fmdb

在那此前我们必要先对应用程序的文件目录有所精通,请看下图

五、执行查询
查询方法
- (FMResultSet *)executeQuery:(NSString*)sql, ...
- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments

示例
// 查询数据
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"];

// 遍历结果集
while ([rs next]) {
 NSString *name = [rs stringForColumn:@"name"];
 int age = [rs intForColumn:@"age"];
 double score = [rs doubleForColumn:@"score"];
}

1.NSKeyedArchiver:(归档)

行使归档的款型来保存数据,该多少对象急需遵从NSCoding探讨,并且该目的对应的类必须提供encodeWithCoder:和initWithCoder:方法。
前一个办法告诉系统怎么对目的开展编码,而后一个主意则是告诉系统怎么对目标开展解码。

三、打开数据库

通过点名SQLite数据库文件路径来创制FMDatabase对象

//获得数据库文件的路径 NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName=[doc stringByAppendingPathComponent:@"student.sqlite"];
 FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
 NSLog(@"数据库打开失败!");
}

文件路径有三种情形

  1. 具体文件路径
      即使不设有会自动创设

  2. 空字符串@””
      会在临时目录创设一个空的数据库
      当FMDatabase连接关闭时,数据库文件也被删去

  3. nil
      会创建一个内存中暂时数据库,当FMDatabase连接关闭时,数据库会被灭绝

网站地图xml地图