iOS開發資料儲存篇—iOS中的幾種資料儲存方式

邏輯教育-楚陽發表於2018-11-29

在專案開發當中,我們經常會對一些資料進行本地快取處理。離線快取的資料一般都儲存在APP所在的沙盒之中。一般有以下幾種:

1、PList(XML屬性列表)

在使用plist進行資料儲存和讀取,只適用於系統自帶的一些常用型別才能用,且必須先獲取路徑相對麻煩

//寫入檔案
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];
複製程式碼

2、偏好設定(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"];
複製程式碼

這是一個我的iOS交流群:624212887,群檔案自行下載,不管你是小白還是大牛熱烈歡迎進群 ,分享面試經驗,討論技術, 大家一起交流學習成長!希望幫助開發者少走彎路。——點選:加入

3、歸檔(NSCoding NSKeyedArchiver NSKeyedUnarchiver)

因為前兩者都有一個致命的缺陷,只能儲存常用的型別。歸檔可以實現把自定義的物件存放在檔案中。

需要儲存的物件必須遵守NSCoding協議,並且實現該協議中- (void)encodeWithCoder:(NSCoder )aCoder和 - (id)initWithCoder:(NSCoder )aDecoder方法。

YXPerson.h檔案如下:

  @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];
複製程式碼

4、SQLITE資料庫

上述三種方法都無法儲存大批量的資料,有效能的問題。

下面簡單介紹一下,如何開啟資料庫,新增一張表格,然後對其進行增刪改查的操作。

- (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(@"查詢語句有問題");
    }
}
複製程式碼

5、FMDB

FMDB是IOS中一個著名的SQLite資料庫操作的開源專案。專案地址為:github.com/ccgus/fmdb

。是對SQLIite資料庫的C語言介面進行了一層封裝,使其滿足物件導向的操作,介面比原生的SQLite介面簡潔很多。同時也提供一些多執行緒,快取,執行緒池的功能。以後的部落格將進行詳細介紹,這裡不多說了。

6、CoreData

是蘋果公司提供的資料持久化的一種方案。以後的部落格將進行詳細介紹,這裡不多說了。

7、最後說一點

這是一個我的iOS交流群:624212887,群檔案自行下載,不管你是小白還是大牛熱烈歡迎進群 ,分享面試經驗,討論技術, 大家一起交流學習成長!希望幫助開發者少走彎路。——點選:加入

如果覺得對你還有些用,就關注小編+喜歡這一篇文章。你的支援是我繼續的動力。

下篇文章預告:NSNotificationCenter使用小結

文章來源於網路,如有侵權,請聯絡小編刪除。


相關文章