iOS數(shù)據(jù)持久化

Title: iOS數(shù)據(jù)持久化

##數(shù)據(jù)持久化概念

數(shù)據(jù)持久化就是將內(nèi)存中的數(shù)據(jù)模型轉(zhuǎn)換為存儲(chǔ)模型,以及將存儲(chǔ)模型轉(zhuǎn)換為內(nèi)存中的數(shù)據(jù)模型的統(tǒng)稱。

##數(shù)據(jù)持久化的好處

1. 程序代碼重用性強(qiáng),即使更換數(shù)據(jù)庫,只需要更改配置文件,不必重寫程序代碼。

2. 業(yè)務(wù)邏輯代碼可讀性強(qiáng),在代碼中不會(huì)有大量的SQL語言,提高程序的可讀性。

3. 持久化技術(shù)可以自動(dòng)優(yōu)化,以減少對(duì)數(shù)據(jù)庫的訪問量,提高程序運(yùn)行效率。

##iOS數(shù)據(jù)持久化方案

- NSUserDefault

- 文件存儲(chǔ) (包括:Plist屬性列表、archive 歸檔、文件流)

- 鑰匙串(keychain)

- 數(shù)據(jù)庫相關(guān) (Core Data、SQLite 3)

###沙盒機(jī)制

在iOS中每個(gè)APP都擁有自己的**沙盒**,APP**只能訪問**對(duì)應(yīng)沙盒中存儲(chǔ)的數(shù)據(jù), iOS是**不允許**跨越沙盒去訪問數(shù)據(jù)的,所有的數(shù)據(jù)都是保存在該沙盒的三個(gè)子目錄下。

###沙盒目錄結(jié)構(gòu)

```

應(yīng)用程序.ipa

Documents

Library

\Caches

\Preferences

Temp

```

- `應(yīng)用程序包`: 這里存放的是應(yīng)用程序的源文件,包括資源文件和可執(zhí)行文件。

```

NSString *ApplicationPath = [[NSBundle mainBundle] bundlePath];

```

- `Document`: 一般在該目錄下保存一些比較重要的數(shù)據(jù),當(dāng)連接 iTunes后會(huì)自動(dòng)同步數(shù)據(jù)。

```

NSString *DocumentPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES).firstObject];

```

`PS:? 如果將數(shù)據(jù)資源保存到該目錄.上架可能會(huì)被拒絕,(解決方案:直接設(shè)置該文件夾不被iTunes備份),總之:不能保存從網(wǎng)上下載的數(shù)據(jù),否則不能上架。`

- `Library`: 存儲(chǔ)應(yīng)用設(shè)置或者狀態(tài)信息等,在該目錄下還有兩個(gè)子目錄: `Caches和Preference`

```

NSString *CachesPath =? [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject];

```

`Library/Caches`: 存放緩存文件,iTunes不會(huì)備份,因此文件不會(huì)因APP退出而刪除(一般使用SDWebImage的緩存資源都是保存到這來)

`Library/Preference`: 保存應(yīng)用的所有偏好設(shè)置,iOS的Setting(設(shè)置)會(huì)在該目錄查找該應(yīng)用的設(shè)置信息,iTunes會(huì)同步數(shù)據(jù)

- temp: 臨時(shí)文件, iTunes不會(huì)備份該文件夾中的數(shù)據(jù), 這個(gè)文件夾中的數(shù)據(jù),會(huì)因?yàn)閼?yīng)用的關(guān)閉而刪除。

```

NSString *tempPath = NSTemporaryDirectory( );

```

###NSUerDefault

小規(guī)模數(shù)據(jù),弱業(yè)務(wù)相關(guān)數(shù)據(jù),都可以放到`NSUserDefault`里面。

- 偏好設(shè)置是專門用來保存應(yīng)用程序的配置信息的,一般不要在偏好設(shè)置中保存其他數(shù)據(jù)。

- 如果沒有調(diào)用`synchronize`方法,系統(tǒng)會(huì)根據(jù)I/O情況不定時(shí)刻地保存到文件中。所以如果需要立即寫入文件的就必須調(diào)用`synchronize`方法。

- 偏好設(shè)置會(huì)將所有數(shù)據(jù)保存到同一個(gè)文件中。即`preference`目錄下的一個(gè)以此應(yīng)用包名來命名的plist文件。

```

//1.獲得NSUserDefaults文件

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

//2.向文件中寫入內(nèi)容

[userDefaults setObject:@"Barry" forKey:@"name"];

[userDefaults setBool:YES forKey:@"male"];

[userDefaults setInteger:20 forKey:@"age"];

//2.1立即同步

[userDefaults synchronize];

//3.讀取文件

NSString *name = [userDefaults objectForKey:@"name"];

BOOL male = [userDefaults boolForKey:@"male"];

NSInteger age = [userDefaults integerForKey:@"age"];

NSLog(@"%@, %d, %ld", name, male, age);

```

###Plist

`plist文件存儲(chǔ)`:是一種明文的輕量級(jí)存儲(chǔ)方式,最常用的格式是XML格式,系統(tǒng)會(huì)提供一個(gè)info.plist文件,這種方式的安全性幾乎為**0**,所以`plist`主要是用于存儲(chǔ)少量并且不重要的數(shù)據(jù)。 `plist`只能讀取數(shù)組(NSArray)或者字典(NSDictonary)。

```

/**

*? Plist文件

*/

NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSString *fileName = [path stringByAppendingPathComponent:@"Person.plist"];

NSDictionary *dict = @{

@"name" : @"Barry",

@"age" : @20,

@"height" : @1.80f

};

// 將數(shù)據(jù)寫入Plist

[dict writeToFile:fileName atomically:YES];

NSLog(@"%@", fileName);

// 讀取plist中的數(shù)據(jù)

NSDictionary *dicts = [NSDictionary dictionaryWithContentsOfFile:fileName];

NSLog(@"dict = %@",dicts);

NSString *str = [NSString stringWithContentsOfFile:fileName encoding:NSUTF8StringEncoding error:nil];

NSLog(@"str = %@", str);

```

###Keychain(鑰匙串)

`Keychain` 是蘋果提供的帶有可逆加密的存儲(chǔ)機(jī)制,普遍用在各種存密碼的需求上。另外,由于App卸載只要系統(tǒng)不重裝,`Keychain`中的數(shù)據(jù)依舊能夠得到保留,以及可被`iCloud`同步的特性,大家都會(huì)在這里存儲(chǔ)用戶唯一標(biāo)識(shí)串。所以有需要加密、需要存`iCloud`的敏感小數(shù)據(jù),一般都會(huì)放在`Keychain`。

###數(shù)據(jù)歸檔/序列化(NSKeyedArchiver)

`NSKeyedArchiver`: 是一種輕量級(jí)存儲(chǔ)的持久化方案,數(shù)據(jù)化歸檔時(shí)經(jīng)過加密處理的,所以安全性遠(yuǎn)高于`plist`。數(shù)據(jù)歸檔可以存儲(chǔ)一些復(fù)雜的對(duì)象,數(shù)據(jù)保存前會(huì)經(jīng)過二進(jìn)制處理。

- 遵循協(xié)議、設(shè)置屬性

```

/*遵循 NSCoding 協(xié)議*/

@interface Student : NSObject

/*設(shè)置屬性*/

@property(nonatomic, copy) NSString *name;

@property(nonatomic, assign) int age;

@property(nonatomic, copy) NSString *gender;

@end

```

```

/*解檔(反序列化)*/

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

if (self == [super init]) {

self.name = [aDecoder decodeObjectForKey:@"name"];

self.age = [aDecoder decodeIntForKey:@"age"];

self.gender = [aDecoder decodeObjectForKey:@"gender"];

}

return self;

}

/**歸檔(序列化)*/

- (void)encodeWithCoder:(NSCoder *)aCoder {

// 歸檔姓名(字符串對(duì)象)

[aCoder encodeObject:self.name forKey:@"name"];

// 歸檔年齡(注意:這是基本數(shù)據(jù)類型, 如果是其他的類型,直接調(diào)用對(duì)應(yīng)類型的encode即可)

[aCoder encodeInteger:self.age forKey:@"age"];

[aCoder encodeObject:self.gender forKey:@"gender"];

}

@end

```

PS:

1. 必須遵循并實(shí)現(xiàn)NSCoding協(xié)議

2. 保存文件的擴(kuò)展名可以任意指定

3. 繼承時(shí)必須先調(diào)用父類的歸檔解檔方法

###數(shù)據(jù)庫(SQLite)

數(shù)據(jù)庫(SQLite3): 是一個(gè)輕量級(jí),跨平臺(tái)的小型數(shù)據(jù)庫,可移植性比較高,有著和`MySql`幾乎相同的數(shù)據(jù)庫語句,以及無需服務(wù)器即可使用的優(yōu)點(diǎn)。

數(shù)據(jù)庫的優(yōu)點(diǎn):

-? 該方案可以存儲(chǔ)大量的數(shù)據(jù),存儲(chǔ)和檢索的速度非常快。

- 能對(duì)數(shù)據(jù)進(jìn)行大量的聚合,這樣比起使用對(duì)象來講操作要快。

數(shù)據(jù)庫的缺點(diǎn):

- 它沒有提供數(shù)據(jù)庫的創(chuàng)建方式。

- 它的底層是基于C語言框架設(shè)計(jì)的,沒有面向?qū)ο蟮腁PI,用起來非常麻煩。

- 發(fā)雜的數(shù)據(jù)模型的數(shù)據(jù)建表,非常麻煩。

在實(shí)際開發(fā)中我們都是使用的是`FMDB`第三方開源的數(shù)據(jù)庫,該數(shù)據(jù)庫是基于`splite`封裝的面向?qū)ο蟮目蚣堋?/p>

###CoreData

`coreData`: 是蘋果官方在iOS5之后推出的綜合性數(shù)據(jù)庫,其使用了對(duì)象關(guān)系映射技術(shù),將對(duì)象轉(zhuǎn)換成數(shù)據(jù),將數(shù)據(jù)存儲(chǔ)在本地的數(shù)據(jù)庫中。

` coreData`為了提高效率,需要將數(shù)據(jù)存儲(chǔ)在不同的數(shù)據(jù)庫中,比如:在使用的時(shí)候,最好是將本地的數(shù)據(jù)保存到內(nèi)存中,這樣的目的是訪問

速度比較快。

PS: CoreData并不是數(shù)據(jù)庫!

使用了對(duì)象關(guān)系映射技術(shù),將對(duì)象轉(zhuǎn)換成數(shù)據(jù),將數(shù)據(jù)存儲(chǔ)在本地的數(shù)據(jù)庫中。底層還是使用 SQLit3。

##下面一篇BLOG,將著重介紹第三方封裝數(shù)據(jù)庫`FMDB`的使用!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容