自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS持久化

移動(dòng)開(kāi)發(fā) iOS
如果我們想在程序中獲取上面某個(gè)目錄的路徑,應(yīng)該如何實(shí)現(xiàn)呢? 下面就講講路徑的獲取, 通過(guò)NSPathUtilities.h中的NSSearchPathForDirectoriesInDomains函數(shù),我們便可以獲取我們想要的路 徑。

1.文件系統(tǒng)

不管是Mac OS X 還是iOS的文件系統(tǒng)都是建立在UNIX文件系統(tǒng)基礎(chǔ)之上的。

1.1 沙盒模型

在iOS中,一個(gè)App的讀寫(xiě)權(quán)限只局限于自己的沙盒目錄中。

沙盒模型到底有哪些好處呢?
安全:別的App無(wú)法修改你的程序或數(shù)據(jù)
保護(hù)隱私:別的App無(wú)法讀取你的程序和數(shù)據(jù)
方便刪除:因?yàn)橐粋€(gè)App所有產(chǎn)生的內(nèi)容都在自己的沙盒中,所以刪除App只需要將沙盒刪除就可以徹底刪除程序了

iOS App沙盒中的目錄

  • App Bundle ,如xxx.app 其實(shí)是一個(gè)目錄,里面有app本身的二進(jìn)制數(shù)據(jù)以及資源文件
  • Documents, 存放程序產(chǎn)生的文檔數(shù)據(jù)
  • Library , 下面默認(rèn)包含下面兩個(gè)目錄 Caches Preferences
  • tmp, 臨時(shí)文件目錄

如果我們想在程序中獲取上面某個(gè)目錄的路徑,應(yīng)該如何實(shí)現(xiàn)呢? 下面就講講路徑的獲取, 通過(guò)NSPathUtilities.h中的NSSearchPathForDirectoriesInDomains函數(shù),我們便可以獲取我們想要的路 徑。 此函數(shù)具體聲明如下:

NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde); 
directory 目錄類型 比如Documents目錄 就是NSDocumentDirectory 
domainMask 在iOS的程序中這個(gè)取NSUserDomainMask 
expandTilde YES,表示將~展開(kāi)成完整路徑

注意函數(shù)返回的類型為數(shù)組,在iOS中一般這個(gè)數(shù)組中只包含一個(gè)元素,所以直接取lastObject即可。

1.2 NSFileManager

NSFileManager提供一個(gè)類方法獲得一個(gè)單例。

 

  1. /* Returns the default singleton instance.*/ + (NSFileManager *)defaultManager; 

下面羅列了NSFileManager的常用方法

  • 新建目錄

 

  1. - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error; 

createIntermediates這個(gè)參數(shù)一般為YES,表示如果目錄路徑中間的某個(gè)目錄不存在則創(chuàng)建之,如果是NO的話,則要保證所創(chuàng)建目錄的父目錄都必須已經(jīng)存在

  • 獲取目錄下的所有文件
  1. - (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error; 

如果目錄為空,則返回空數(shù)組

  • 其他的一些方法

 

  1. - (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)linkItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error; 

更多的可以查看文檔 NSFileManager Class Reference

在實(shí)際項(xiàng)目中,我們一般會(huì)寫(xiě)一個(gè)工具類來(lái)負(fù)責(zé)項(xiàng)目中所有的路徑操作。

2. 歸檔(Archives) 和 序列化(Serializations)

我們經(jīng)常聽(tīng)到“序列化”,“反序列化”這樣的字眼,其實(shí)“序列化”的意思就是將對(duì)象轉(zhuǎn)換成字節(jié)流以便保存或傳輸,“反序列化”便是一個(gè)相反的過(guò)程,從字節(jié)流轉(zhuǎn)到對(duì)象。

在這節(jié)中涉及到一種文件類型plist,plist就是Property List 的縮寫(xiě),即所謂的屬性列表,屬性列表有兩種數(shù)據(jù)格式,一種是XML的,方便閱讀和編輯;另一種是二進(jìn)制的,節(jié)省存儲(chǔ)空間,以及提高效率。

在Objective-C中這個(gè)對(duì)象和字節(jié)流的互轉(zhuǎn)分成兩類:

  • 歸檔 普通自定義對(duì)象和字節(jié)流之間的轉(zhuǎn)換
  • 序列化 某些特定類型(NSDictionary, NSArray, NSString, NSDate, NSNumber,NSData)的數(shù)據(jù)和字節(jié)流之間(通常將其保存為plist文件)的轉(zhuǎn)換

不過(guò)本質(zhì)上講上述兩種都是對(duì)象圖(Object Graph)和字節(jié)流之間的轉(zhuǎn)換. Apple關(guān)于序列化和歸檔的編程指南: Archives and Serializations Programming Guide 。

2.1 歸檔

如果我們需要將自定義的一個(gè)對(duì)象保存到文件,應(yīng)該如何做呢? 
這里引入兩個(gè)東西:一個(gè)是NSCoding協(xié)議 ;另一個(gè)是NSKeyedArchiver,NSKeyedArchiver其實(shí)繼承于NSCoder,可以以鍵值對(duì)的方式將對(duì)象的屬性進(jìn)行序列化和反序列化。 
具體的過(guò)程可以這樣描述 通過(guò)NSKeyedArchiver 可以將實(shí)現(xiàn)了NSCoding協(xié)議的對(duì)象 和 字節(jié)流 相互轉(zhuǎn)換 。

像一些框架中的數(shù)據(jù)類型如NSDictionary,NSArray,NSString... 都已經(jīng)實(shí)現(xiàn)了NSCoding協(xié)議,所以可以直接對(duì)他們進(jìn)行歸檔操作。

這里來(lái)一個(gè)比較完整的例子,一個(gè)Address類,一個(gè)User類,User類下有個(gè)Address類型的屬性。

Address類

User類

使用示例

通過(guò)查看文件內(nèi)容可以發(fā)現(xiàn),保存的是plist的二進(jìn)制數(shù)據(jù)格式。 轉(zhuǎn)成XML可以看到如下內(nèi)容:

2.2 序列化

在實(shí)際的項(xiàng)目中,我們一般是將NSDictionary或NSArray的對(duì)象保存到文件或者從文件讀取成對(duì)象。 當(dāng)然這種只是適用于數(shù)據(jù)量不是很大的應(yīng)用場(chǎng)景。 NSDictionary和NSArray 都有一個(gè)寫(xiě)入文件的方法

NSDictionary和NSArray會(huì)直接寫(xiě)成plist文件。

2.2.1 序列化的方式

序列化可以通過(guò)兩種途徑來(lái)進(jìn)行

使用數(shù)據(jù)對(duì)象自帶的方法

寫(xiě)文件

寫(xiě)完的文件內(nèi)容如下:

從文件讀取

使用NSPropertyListSerialization類

通過(guò)NSPropertyListSerialization類可以將數(shù)據(jù)對(duì)象直接轉(zhuǎn)成NSData或者直接寫(xiě)到文件或者流中去.

讀取

2.2.2 User Defaults

User Defaults 顧名思義就是一個(gè)用戶為系統(tǒng)以及程序設(shè)置的默認(rèn)值。每個(gè)用戶都有自己的一套數(shù)據(jù),用戶和用戶之間沒(méi)法共享的。

我們都知道每一個(gè)程序都會(huì)保存一些設(shè)置數(shù)據(jù),比如記住上次窗口的位置和大小,記住是否彈出某些提示信息等。蘋(píng)果提供了一個(gè)統(tǒng)一的解決方案,就是每一 個(gè)app都有一個(gè)plist文件專門(mén)用以保存偏好設(shè)置數(shù)據(jù)。 plist文件名默認(rèn)是程序Bundle identifier,擴(kuò)展名為plist.

除了程序自己的設(shè)置外,系統(tǒng)還有一些全局的或者其它的一些設(shè)置,也屬于User Defaults的范疇,User Defaults的持久化數(shù)據(jù)都保存在 ~/Library/Preferences 目錄中.

這里有一點(diǎn)簡(jiǎn)要的說(shuō)一下,User Defaults 中存放的key value分放在多個(gè)Domain中,取的時(shí)候按一定的次序取查找,次序如下:

  • The Argument Domain 程序啟動(dòng)的時(shí)候以參數(shù)的方式傳入的
  • The Application Domain 通過(guò)NSUserDefaults往里面寫(xiě)數(shù)據(jù)的時(shí)候默認(rèn)就是寫(xiě)到這個(gè)Domain的,通過(guò)Bundle identifier來(lái)標(biāo)識(shí)
  • The Global Domain 用戶的全局的設(shè)置(系統(tǒng)的偏好設(shè)置)會(huì)放在這個(gè)Domain下,比如用戶的語(yǔ)言設(shè)置,滾動(dòng)條的設(shè)置等,里面的設(shè)置會(huì)對(duì)所有的程序起作用。
  • The Languages Domains
  • The Registration Domain 這個(gè)domain里面的key value是提供默認(rèn)值的,一般會(huì)在程序啟動(dòng)的設(shè)置進(jìn)行設(shè)置,他們都不會(huì)被持久化到文件的。當(dāng)某個(gè)key對(duì)應(yīng)的值在上面的那些domain中都不存在的時(shí)候,就到這里找。

Mac系統(tǒng)還為user defaults提供了很好的命令行工具,defaults 你可以通過(guò)下面的方式查看具體使用方式

可以通過(guò)defaults domains查看當(dāng)前用戶的所有的domain,通過(guò) defaults read NSGlobalDomain 讀取 The Global Domain 中的所有值。

NSUserDefaults 類來(lái)讀寫(xiě)Preferences設(shè)置,而無(wú)需考慮文件位置等細(xì)節(jié)問(wèn)題。

NSUserDefaults 用起來(lái)和 NSDictionary 很相似,多了一個(gè)Domain的概念在里面。NSUserDefaults 一樣提供了一個(gè)獲取單例的方法.

NSUserDefaults提供了一系列的接口來(lái)根據(jù)key獲取對(duì)應(yīng)的value,搜索的次序按照上面提及到的次序在各個(gè)Domain中進(jìn)行查找。還提供了一系列的 Setting Default Values的方法,這些設(shè)置的值都是在 The Application Domain 下的.當(dāng)然也提供了修改其他Domain下的值的方法,只是需要整體的設(shè)置。

3.數(shù)據(jù)庫(kù)

Mac上自帶安裝了SQLite3 ,如果你之前接觸過(guò)關(guān)系型數(shù)據(jù)庫(kù),你可以通過(guò)命令行來(lái)對(duì)SQLite進(jìn)行初步的認(rèn)識(shí)

那如果在代碼中使用SQLite呢?

  • 添加sqlite的動(dòng)態(tài)鏈接庫(kù) libsqlite3.0.dylib
  • 引入頭文件 #import "sqlite3.h"

這樣之后你便可以通過(guò)C的接口來(lái)操作數(shù)據(jù)庫(kù)了

 

你會(huì)發(fā)現(xiàn)這完全是C語(yǔ)言編程,和Objective-C的代碼混在一起格格不入,也很不方便,所以便有人開(kāi)發(fā)了開(kāi)源的sqlite c接口的wrapper

具體的使用方法,各自的文檔都寫(xiě)的比較清楚。 FMDB不支持多線程同時(shí)使用同一個(gè)數(shù)據(jù)庫(kù)連接進(jìn)行操作,否則會(huì)有線程安全問(wèn)題,有可能導(dǎo)致數(shù)據(jù)庫(kù)文件損壞。EGODatabase則引入了多線程的支 持,部分代碼借鑒了FMDB,兩者在使用上非常的相似。另EGODatabase提供了異步數(shù)據(jù)庫(kù)操作的支持,將數(shù)據(jù)庫(kù)操作封裝成數(shù)據(jù)庫(kù)請(qǐng)求(其繼承于 NSOperation),數(shù)據(jù)庫(kù)請(qǐng)求創(chuàng)建好了,丟到一個(gè)OperationQueue中被異步的進(jìn)行執(zhí)行,當(dāng)請(qǐng)求數(shù)據(jù)完成之后 ,相應(yīng)的delegate方法會(huì)被調(diào)用,然后你可以在主線程更新顯示了.

4.CoreData

由于coreData有點(diǎn)小復(fù)雜,就先不講了。。。

 

責(zé)任編輯:張葉青 來(lái)源: 開(kāi)源社區(qū)
相關(guān)推薦

2015-10-15 09:54:31

應(yīng)用架構(gòu)本地化iOS

2024-03-26 00:03:08

Redis數(shù)據(jù)RDB

2015-07-20 09:26:09

iOS數(shù)據(jù)庫(kù)存儲(chǔ)

2009-06-01 13:26:37

持久化規(guī)范JPAJava

2023-10-12 13:01:29

Redis數(shù)據(jù)庫(kù)

2020-03-03 14:15:49

Redis持久化數(shù)據(jù)庫(kù)

2021-03-18 08:18:15

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

2019-12-27 13:50:04

JavaAPI代碼

2009-09-24 15:42:44

Hibernate對(duì)象

2024-12-20 12:15:06

RedisRDB持久化

2009-09-24 16:39:20

Hibernate傳播

2009-08-26 18:05:25

ViewState持久

2021-11-18 13:14:08

DDD聚合代碼

2022-11-29 08:05:48

KubernetesPVCSI

2020-02-18 16:14:33

RedisRDBAOF

2009-09-25 17:19:28

Hibernate持久

2009-09-28 15:50:53

Hibernate創(chuàng)建持久化Product

2009-09-29 16:11:45

Hibernate實(shí)現(xiàn)

2009-09-29 16:46:01

創(chuàng)建Hibernate

2021-10-04 21:11:18

Redis混合持久化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)