博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS数据本地存储的四种方式--
阅读量:5158 次
发布时间:2019-06-13

本文共 7697 字,大约阅读时间需要 25 分钟。

注:借鉴于:http://blog.csdn.net/jianjianyuer/article/details/8556024

      在IOS开发过程中,不管是做什么应用,都会碰到数据保存问题。将数据保存到本地,能够让程序更加流畅,不会出现让人厌恶的菊花状,使得用户的体验更好。下面是介绍数据保存的方式

 

 

第一、NSKeyedArchiver:采用归档的形式来保存数据。(归档——解档)———大量数据和频繁读写不合适使用

  1、归档器的作用是将任意的对象集合转换为字节流。这听起来像是NSPropertyListSerialization类采用的过程,但是它们之间有一个重要的区别。属性列表序列化只能转换一个有限集合的数据类型(大多是数量类型),而归档可以转换任意的OC对象、数据类型、数组、结构、字符串以及更多其他类型。

  2、Foundatio框架支持两种归档器。顺序归档和基于键的归档。基于键的归档器更加灵活,是应用程序开发中推荐使用的归档器 。

  3、一个面向对象程序在运行的时候,一般都创建了一个复杂的对象关系图,经常需要把这样一个复杂的对象关系图表示成字节流,这样的过程叫做          Archiving.

  4、而当从字节流中重新恢复对象关系图的过程叫做unarchive。

  5、NSCoder是archivie字节流的抽象类。

  6、对一个对象归档需要满足的条件是:该对象的类必须实现NSCoding协议

归档、

-(int)create:(Note *)model{    NSString *homeDictionary = NSHomeDirectory();    NSString *path = [homeDictionary stringByAppendingPathComponent:FILE_NAME];    NSFileManager *fileManager = [NSFileManager defaultManager];        BOOL isexists = [fileManager fileExistsAtPath:path];    NSMutableArray *array = [[NSMutableArray alloc] init];    [array addObject:model];       //archive归档    NSMutableData *theData = [NSMutableData data];    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];    [archiver encodeObject:array forKey:ARCHIVE_KEY];    [archiver finishEncoding];        [theData writeToFile:path atomically:YES];//    [array writeToFile:path atomically:YES];        return 0; }

 

解档、

-(NSMutableArray *)findAll{    NSString *homeDictionary = NSHomeDirectory();    NSString *path = [homeDictionary stringByAppendingPathComponent:FILE_NAME];    NSMutableArray *listData = [[NSMutableArray alloc] init];    NSData *theData = [NSData dataWithContentsOfFile:path];        if([theData length]>0)    {        NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];        listData = [archiver decodeObjectForKey:ARCHIVE_KEY];        [archiver finishDecoding];    }    return listData;}

 

第二、NSUserDefaults

 

//自动登陆用到的 +(id)configForKey:(NSString *)key{    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];    return [defaults objectForKey:key];}//写入内容+(void)setLoginConfig:(id)value forKey:(NSString *)key{    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];    [user setObject:value forKey:key];    [user synchronize];   //及时强制写入} //读出内容+(NSString *)getLoginConfig:(NSString *)key{    NSString *s = [Globle  configForKey:key];    if(s==nil)    {        return @"";    }    return s; }

 

 

第三、write写入磁盘

第一步:获得文件即将保存的路径:

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

NSString *ourDocumentPath =[documentPaths objectAtIndex:0];
还有一种方法是使用NSHomeDirectory函数获得sandbox的路径。具体的用法为:
NSString *sandboxPath = NSHomeDirectory();
// Once you have the full sandbox path, you can create a path from it,但是不能在sandbox的本文件层上写文件也不能创建目录,而应该是此基础上创建一个新的可写的目录,例如Documents,Library或者temp。
NSString *documentPath = [sandboxPath
            stringByAppendingPathComponent:@"Documents"];//将Documents添加到sandbox路径上,具体原因前面分析了!

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

 

第二步:生成在该路径下的文件:

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

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

[data writeToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName

 

最后:从文件中读出数据:

NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据

第四、SQLite数据库

@interface BaseViewController (){    sqlite3 *sqlDataBase;}@end @implementation BaseViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];    if (self) {        // Custom initialization    }    return self;} - (void)viewDidLoad{    [super viewDidLoad];    if ([self createOrOpen:@"test.db"]) {//        [self createUserTable:sqlDataBase];//        [self insertMBkey:nil];        NSMutableArray *s = [NSMutableArray new];        [self GetList:s];        NSLog(@"%@",s);    }else    {        NSLog(@"FAIL");    }}

 

/** *该函数主要打开数据库myDataBase.sql,如果该数据库不存在,则进行创建 *打开或者创建成功返回yes,否则返回false,参数dbName是数据库的名称 **/-(BOOL)createOrOpen:(NSString *)dbName{    //获取用户域覆径信息    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocuemntDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];    /**     *Users/admin/Library/Application Support/iPhone Simulator/7.1/Applications/8E23557E-AAA6-471A-AAFE-E036BF1B7E4C/Library/Documentation     *判断用户域是否有数据库dbNmae     */    NSString *path = [documentsDirectory stringByAppendingPathComponent:dbName];    NSFileManager *fileManageer = [NSFileManager defaultManager];    //如果用户域内有该数据库,则返回yes,否则返回NO    BOOL find = [fileManageer fileExistsAtPath:path];    if(find)   //对找到进行处理,如果找到了,并且打开了,则返回yes    {        //打开该数据库,如果打开失败,则返回NO,否则返回yes        if(sqlite3_open([path UTF8String], &sqlDataBase)!= SQLITE_OK)           {               //关闭sqlDataBase,实际是释放了它               sqlite3_close(sqlDataBase);               return NO;           }           return YES;    }  NSLog(@"%d",sqlite3_open([path UTF8String], &sqlDataBase));         //创建数据库,创建返回yes,并且打开数据库,否则返回NO    if(sqlite3_open([path UTF8String], &sqlDataBase)==SQLITE_OK)    {       return YES;    }else    {     //关闭sqlDataBase,实际是释放了它        sqlite3_close(sqlDataBase);        return NO;    }    return NO;}//在打开的数据库中创建表,其中sqldb为成功打开的数据库的sqlite3对象-(BOOL)createUserTable:(sqlite3 *)sqlDataBas{    //设置sql语句    char *sql = "create table user(id integer primary key, name text, address text, imageData BLOB, imageLen integer)";    sqlite3_stmt *statement;  //这个相当于ODBC的Command对象,用于保存编译好的SQL语句    //进行预处理,预处理失败返回NO    if(sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, nil)!=SQLITE_OK)    {        return NO;    }    //预处理成功,进行执行创建操作    int success = sqlite3_step(statement);    sqlite3_finalize(statement);    if(success !=SQLITE_DONE)    {        return NO;    }    return YES;        }//向表中插入数据-(void)insertMBkey:(NSString *)key{    BOOL isOK = NO;    sqlite3_stmt *statement;    static char *sql = "INSERT INTO user VALUES ('1', 'Bill', '河南', 'ssss','2')";    int success = sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, NULL);    if(success !=SQLITE_OK)    {        isOK = NO;    }else    {        sqlite3_bind_text(statement, 1, [key UTF8String], -1, SQLITE_TRANSIENT);        success = sqlite3_step(statement);        sqlite3_finalize(statement);    }        if(success ==SQLITE_ERROR)    {        isOK = NO;    }else    {        isOK=YES;    }        return;}//查询数据-(void)GetList:(NSMutableArray *)KeysList{    BOOL  isOK = NO;    sqlite3_stmt *statement;    static char *sql = "select id,address from user";    int success = sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, NULL);    if(success !=SQLITE_OK)    {        isOK = NO;    }else    {        //查询结果集中一条一条地遍历所有记录,这里的数字对应的时列值        while (sqlite3_step(statement)==SQLITE_ROW) {            int kid = sqlite3_column_int(statement, 0);            char *key = (char  *)sqlite3_column_text(statement, 1);            UserInfo *userModel = [[UserInfo alloc] init];                        userModel.userId =kid;            if (key) {              userModel.userAddress = [NSString stringWithUTF8String:key];            }                [KeysList addObject:userModel];            sqlite3_finalize(statement);        }        NSLog(@"%@",KeysList);        if(success==SQLITE_ERROR)        {            isOK = NO;        }else        {            isOK = YES;        }        return;    } }

 

 

转载于:https://www.cnblogs.com/zhanggui/p/3927986.html

你可能感兴趣的文章
【UOJ#77】A+B Problem
查看>>
【LuoguP5328】[ZJOI2019]浙江省选
查看>>
MeteoInfoLab脚本示例:计算垂直螺旋度
查看>>
Visual Studio的Debugger Visualizers
查看>>
《大教堂与集市》读后感
查看>>
[RabbitMQ]Windows环境下rabbitmqclt(Command Line Tools)出现Erlang distribution failed错误的解决方法...
查看>>
创业这三年@各种奇遇
查看>>
正确配置调试world wind on vs2008
查看>>
纯css实现3D动画
查看>>
几种按键消抖方案的verilog描述
查看>>
四则运算 Day2
查看>>
使用SpringBoot生成项目
查看>>
C++ __super关键词用法
查看>>
FTP上传及下载
查看>>
作业5 四则运算 测试与封装 5.1
查看>>
实验7
查看>>
双系统更改启动顺序
查看>>
用参数较少的函数替换参数较多的函数
查看>>
【转】函数中的形参问题(指针形参、引用形参、二重指针作为形参)
查看>>
location对象查询字符串参数
查看>>