發表於2016/4/5 21:02:09 421人閱讀git
分類: 數據存儲github
在項目開發當中,咱們常常會對一些數據進行本地緩存處理。離線緩存的數據通常都保存在APP所在的沙盒之中。通常有如下幾種:objective-c
在使用plist進行數據存儲和讀取,只適用於系統自帶的一些經常使用類型才能用,且必須先獲取路徑相對麻煩sql
//寫入文件 NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [doc stringByAppendingPathComponent:@"myself.plist"]; NSDictionary *dict = @{@"name": @"yixiang"}; [dict writeToFile:path atomically:YES]; //讀取文件 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
二、偏好設置(NSUserDefaults)數據庫
將全部的東西都保存在同一個文件夾下面,且主要用於存儲應用的設置信息)緩存
//寫入文件 NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; [defaults setObject:@"yixiang" forKey:@"name"]; [defaults setInteger:27 forKey:@"age"]; [defaults synchronize]; //讀取文件 NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; NSString *name=[defaults objectForKey:@"name"]; NSInteger age=[defaults integerForKey:@"age"];
由於前二者都有一個致命的缺陷,只能存儲經常使用的類型。歸檔能夠實現把自定義的對象存放在文件中。markdown
須要保存的對象必須遵照NSCoding協議,而且實現該協議中- (void)encodeWithCoder:(NSCoder )aCoder和 - (id)initWithCoder:(NSCoder )aDecoder方法。多線程
YXPerson.h文件以下:dom
@interface YXPerson : NSObject<NSCoding> @property(nonatomic,copy) NSString *name; @property(nonatomic,assign) int age; @end
YXPerson.m文件以下:函數
#import "YYPerson.h" @implementation YYPerson -(void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeInteger:self.age forKey:@"age"]; } -(id)initWithCoder:(NSCoder *)aDecoder{ if (self=[super init]) { self.name=[aDecoder decodeObjectForKey:@"name"]; self.age=[aDecoder decodeIntegerForKey:@"age"]; } return self; } @end
在ViewController中對它進行寫入和讀取
//寫入對象 YXPerson *p=[[YXPerson alloc]init]; p.name=@"yixiang"; p.age=27; NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; NSString *path=[docPath stringByAppendingPathComponent:@"person.yixiang"]; [NSKeyedArchiver archiveRootObject:p toFile:path]; //讀取對象 YXPerson *p=[NSKeyedUnarchiver unarchiveObjectWithFile:path];
上述三種方法都沒法存儲大批量的數據,有性能的問題。
下面簡單介紹一下,如何打開數據庫,新增一張表格,而後對其進行增刪改查的操做。
- (void)openDB{ //獲取數據庫文件路徑 NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *fileName = [doc stringByAppendingPathComponent:@"students.sqlite"]; //將OC字符串轉換爲c語言的字符串 const char *cfileName = fileName.UTF8String; //打開數據庫文件(若是數據庫文件不存在,那麼該函數會自動建立數據庫文件) int result = sqlite3_open(cfileName, &_db); if (result == SQLITE_OK) {//打開成功 NSLog(@"成功打開數據庫"); }else{ NSLog(@"打開數據庫失敗"); } } - (void)createTable{ //建立表 const char *sql = "CREATE TABLE IF NOT EXISTS t_student(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,age integer NOT NULL);"; char *errmsg= NULL; int result = sqlite3_exec(_db, sql, NULL, NULL, &errmsg); if (result==SQLITE_OK) { NSLog(@"建立表成功"); }else{ NSLog(@"建立表失敗---%s",errmsg); } } - (void)insertData{ //插入數據 for (int i=0; i<10; i++) { //拼接sql語句 NSString *name = [NSString stringWithFormat:@"yixiangboy--%d",arc4random_uniform(100)]; int age = arc4random_uniform(20)+10; NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student (name,age) VALUES ('%@',%d);",name,age]; //執行SQL語句 char *errmsg = NULL; sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg); if (errmsg) {//若是有錯誤信息 NSLog(@"插入數據失敗--%s",errmsg); }else{ NSLog(@"插入數據成功"); } } } - (void)deleteData{ //刪除age小於15的數據 NSString *sql = [NSString stringWithFormat:@"DELETE FROM t_student WHERE age<15"]; char *errmsg = NULL; sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg); if (errmsg) { NSLog(@"刪除數據失敗"); }else{ NSLog(@"刪除數據成功"); } } - (void)updateData{ //大於20歲的都置爲20歲 NSString *sql = [NSString stringWithFormat:@"UPDATE t_student set age=20 WHERE age>20"]; char *errmsg = NULL; sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg); if (errmsg) { NSLog(@"更新數據失敗"); }else{ NSLog(@"更新數據成功"); } } - (void)queryData{ const char *sql = "SELECT id,name,age FROM t_student WHERE age<20"; sqlite3_stmt *stmt = NULL; //進行查詢前的準備工做 if(sqlite3_prepare_v2(_db, sql, -1, &stmt, NULL)==SQLITE_OK){//SQL語句沒有問題 NSLog(@"查詢語句沒有問題"); //每調用一次sqlite3_step函數,stmt就會指向下一條記錄 while (sqlite3_step(stmt)==SQLITE_ROW) {//找到一條記錄 //取出數據 //(1)取出第0個字段的值(int) int ID=sqlite3_column_int(stmt, 0); //(2)取出第一列字段的值(text) const unsigned char *name = sqlite3_column_text(stmt, 1); //(3)取出第二列字段的值(int) int age = sqlite3_column_int(stmt, 2); printf("%d %s %d\n",ID,name,age); } }else{ NSLog(@"查詢語句有問題"); } }
FMDB是IOS中一個著名的SQLite數據庫操做的開源項目。項目地址爲:https://github.com/ccgus/fmdb
。是對SQLIite數據庫的C語言接口進行了一層封裝,使其知足面向對象的操做,接口比原生的SQLite接口簡潔不少。同時也提供一些多線程,緩存,線程池的功能。之後的博客將進行詳細介紹,這裏很少說了。
是蘋果公司提供的數據持久化的一種方案。之後的博客將進行詳細介紹,這裏很少說了。
微博:新浪微博