每個ios應用都有自己的應用沙盒(應用沙盒就是檔案系統目錄),與其他檔案系統隔離。應用必須待在自己的沙盒裡,其他應用不能通路該沙盒
應用沙盒的檔案系統目錄,如下圖所示(假設應用的名稱叫layer)
應用沙盒的檔案系統目錄
應用沙盒結構分析
應用程式包:(上圖中的layer)包含了所有的資源檔案和可執行檔案
documents:儲存應用運作時生成的需要持久化的資料,itunes同步裝置時會備份該目錄。例如,遊戲應用可将遊戲存檔儲存在該目錄
tmp:儲存應用運作時所需的臨時資料,使用完畢後再将相應的檔案從該目錄删除。應用沒有運作時,系統也可能會清除該目錄下的檔案。itunes同步裝置時不會備份該目錄
library/caches:儲存應用運作時生成的需要持久化的資料,itunes同步裝置時不會備份該目錄。一般存儲體積大、不需要備份的非重要資料
library/preference:儲存應用的所有偏好設定,ios的settings(設定)應用會在該目錄中查找應用的設定資訊。itunes同步裝置時會備份該目錄
應用沙盒目錄的常見擷取方式
沙盒根目錄:nsstring *home = nshomedirectory();
documents:(2種方式)
利用沙盒根目錄拼接”documents”字元串
利用nssearchpathfordirectoriesindomains函數
tmp:nsstring *tmp = nstemporarydirectory();
library/caches:(跟documents類似的2種方法)
利用沙盒根目錄拼接”caches”字元串
利用nssearchpathfordirectoriesindomains函數(将函數的第2個參數改為:nscachesdirectory即可)
library/preference:通過nsuserdefaults類存取該目錄下的設定資訊
<a target="_blank" href="#xml%e5%b1%9e%e6%80%a7%e5%88%97%e8%a1%a8%ef%bc%88plist%ef%bc%89%e5%bd%92%e6%a1%a3">xml屬性清單(plist)歸檔</a>
<a target="_blank" href="#preference%ef%bc%88%e5%81%8f%e5%a5%bd%e8%ae%be%e7%bd%ae%ef%bc%89">preference(偏好設定)</a>
<a target="_blank" href="#nskeyedarchiver%e5%bd%92%e6%a1%a3%ef%bc%88nscoding%ef%bc%89">nskeyedarchiver歸檔(nscoding)</a>
<a target="_blank" href="#sqlite3">sqlite3</a>
<a target="_blank" href="#coredata">core data</a>
屬性清單是一種xml格式的檔案,拓展名為plist
如果對象是<code>nsstring</code>、<code>nsdictionary</code>、<code>nsarray</code>、<code>nsdata</code>、<code>nsnumber</code>等類型,就可以使用<code>writetofile:atomically:</code>方法直接将對象寫到屬性清單檔案中
舉個例子
将一個nsdictionary對象歸檔到一個plist屬性清單中
成功寫入到documents目錄下:
運作結果
用文本編輯器打開,檔案内容為:
文本編輯器檢視
用xcode打開屬性檔案:
xcode檢視
讀取屬性清單,恢複nsdictionary對象
輸出結果
屬性清單-nsdictionary的存儲和讀取過程
很多ios應用都支援偏好設定,比如儲存使用者名、密碼、字型大小等設定,ios提供了一套标準的解決方案來為應用加入偏好設定功能
每個應用都有個nsuserdefaults執行個體,通過它來存取偏好設定
比如,儲存使用者名、字型大小、是否自動登入
存儲檔案内容
如果對象是nsstring、nsdictionary、nsarray、nsdata、nsnumber等類型,可以直接用nskeyedarchiver進行歸檔和恢複
不是所有的對象都可以直接用這種方法進行歸檔,隻有遵守了nscoding協定的對象才可以
nscoding協定有2個方法:
encodewithcoder:
每次歸檔對象時,都會調用這個方法。一般在這個方法裡面指定如何歸檔對象中的每個執行個體變量,可以使用encodeobject:forkey:方法歸檔執行個體變量
initwithcoder:
每次從檔案中恢複(解碼)對象時,都會調用這個方法。一般在這個方法裡面指定如何解碼檔案中的資料為對象的執行個體變量,可以使用decodeobject:forkey方法解碼執行個體變量
歸檔成功
存檔檔案
恢複(解碼)nsarray對象
存取過程
person.h
person.m
歸檔(編碼)
恢複(解碼)
使用archiverootobject:tofile:方法可以将一個對象直接寫入到一個檔案中,但有時候可能想将多個對象寫入到同一個檔案中,那麼就要使用nsdata來進行歸檔對象
nsdata可以為一些資料提供臨時存儲空間,以便随後寫入檔案,或者存放從磁盤讀取的檔案内容。可以使用[nsmutabledata data]建立可變資料空間
原理
舉個例子:nsdata-歸檔2個person對象到同一檔案中
歸檔(編碼)
恢複(解碼)
ps:也可将多個對象放入到一個數組中。
将數組進行歸檔,在數組對象執行archiverootobject:tofile時,數組中每個對象會自動調用encodewithcoder:方法進行歸檔;
相反數組檔案進行解檔時,在數組對象執行unarchiveobjectwithfile:時,數組中每個對象會自動調用initwithcoder:方法進行解檔。
比如對一個person對象進行深複制
深複制原理
sqlite3是一款開源的嵌入式關系型資料庫,可移植性好、易使用、記憶體開銷小
sqlite3是無類型的,意味着你可以儲存任何類型的資料到任意表的任意字段中。比如下列的創表語句是合法的:
為了保證可讀性,建議還是把字段類型加上:
sqlite3常用的5種資料類型:text、integer、float、boolean、blob
在ios中使用sqlite3,首先要添加庫檔案libsqlite3.dylib和導入主頭檔案
導入庫
建立或打開資料庫
代碼解析:
sqlite3_open()将根據檔案路徑打開資料庫,如果不存在,則會建立一個新的資料庫。如果result等于常量sqlite_ok,則表示成功打開資料庫
sqlite3 *db:一個打開的資料庫執行個體
資料庫檔案的路徑必須以c字元串(而非nsstring)傳入
關閉資料庫:sqlite3_close(db);
執行創表語句
sqlite3_exec()可以執行任何sql語句,比如創表、更新、插入和删除操作。但是一般不用它執行查詢語句,因為它不會傳回查詢到的資料
sqlite3_exec()還可以執行的語句:
開啟事務:begin transaction;
復原事務:rollback;
送出事務:commit;
sqlite3_prepare_v2()傳回值等于sqlite_ok,說明sql語句已經準備成功,沒有文法問題
sqlite3_bind_text():大部分綁定函數都隻有3個參數
第1個參數是sqlite3_stmt *類型
第2個參數指占位符的位置,第一個占位符的位置是1,不是0
第3個參數指占位符要綁定的值
第4個參數指在第3個參數中所傳遞資料的長度,對于c字元串,可以傳遞-1代替字元串的長度
第5個參數是一個可選的函數回調,一般用于在語句執行後完成記憶體清理工作
sqlite_step():執行sql語句,傳回sqlite_done代表成功執行完畢
sqlite_finalize():銷毀sqlite3_stmt *對象
代碼解析
sqlite3_step()傳回sqlite_row代表周遊到一條新記錄
sqlite3_column_*()用于擷取每個字段對應的值,第2個參數是字段的索引,從0開始
core data架構提供了對象-關系映射(orm)的功能,即能夠将oc對象轉化成資料,儲存在sqlite3資料庫檔案中,也能夠将儲存在資料庫中的資料還原成oc對象。在此資料操作期間,不需要編寫任何sql語句。使用此功能,要添加coredata.framework和導入主頭檔案coredata/coredata.h
對象-關系映射
在core data,需要進行映射的對象稱為<code>實體</code>(entity),而且需要使用core data的模型檔案來描述應用的所有實體和實體屬性
這裡以person和card(身份證)2個實體為例子,先看看實體屬性和之間的關聯關系
實體屬性和之間的關聯關系
person中有個card屬性,card中有個person屬性
屬于一對一雙向關聯
建立檔案
添加實體
這裡寫圖檔描述
添加person實體的基本屬性
添加card實體的基本屬性
在person中添加card屬性
在card中添加person屬性
通過core data從資料庫取出的對象,預設情況下都是nsmanagedobject對象
nsmanagedobject的工作模式有點類似于nsdictionary對象,通過鍵-值對來存取所有的實體屬性
setvalue:forkey: 存儲屬性值(屬性名為key)
valueforkey: 擷取屬性值(屬性名為key)
從應用程式包中加載模型檔案
傳入模型,初始化nspersistentstorecoordinator
建構sqlite檔案路徑
添加持久化存儲庫,這裡使用sqlite作為存儲庫
初始化上下文,設定persistentstorecoordinator屬性
傳入上下文,建立一個person實體對象
設定簡單屬性
傳入上下文,建立一個card實體對象
設定person和card之間的關聯關系
利用上下文對象,将資料同步到持久化存儲庫
初始化一個查詢請求
設定要查詢的實體
設定排序(按照age降序)
設定條件過濾(name like '%hosea-1%')
執行請求
周遊資料
core data不會根據實體中的關聯關系立即擷取相應的關聯對象
比如通過core data取出person實體時,并不會立即查詢相關聯的card實體;當應用真的需要使用card時,才會查詢資料庫,加載card實體的資訊
預設情況下,利用core data取出的實體都是nsmanagedobject類型的,能夠利用鍵-值對來存取資料
但是一般情況下,實體在存取資料的基礎上,有時還需要添加一些業務方法來完成一些其他任務,那麼就必須建立nsmanagedobject的子類
選擇模型檔案
選擇需要建立子類的實體
那麼生成一個person實體對象就應該這樣寫
原文連結:http://www.jianshu.com/p/a3eeae99e902