iOS 應(yīng)用沙盒宫屠,歸檔,解檔滑蚯,偏好設(shè)置浪蹂,plist存儲(chǔ),NSData告材,自定義對(duì)象歸檔解檔

1坤次、iOS應(yīng)用數(shù)據(jù)存儲(chǔ)的常用方式

  • XML屬性列表(plist)歸檔
  • Preference(偏好設(shè)置)
  • NSKeyedArchiver歸檔(NSCoding)
  • SQLite3
  • Core Data

2、應(yīng)用沙盒

每個(gè)iOS應(yīng)用都有自己的應(yīng)用沙盒(應(yīng)用沙盒就是文件系統(tǒng)目錄)斥赋,與其他文件系統(tǒng)隔離缰猴。應(yīng)用必須待在自己的沙盒里,其他應(yīng)用不能訪問(wèn)該沙盒
應(yīng)用沙盒的文件系統(tǒng)目錄疤剑,如下圖所示(假設(shè)應(yīng)用的名稱叫Layer)
模擬器應(yīng)用沙盒的根路徑在: (apple是用戶名, 8.0是模擬器版本)
/Users/apple/Library/Application Support/iPhone Simulator/8.0/Applications

3滑绒、應(yīng)用沙盒結(jié)構(gòu)分析

應(yīng)用程序包:(上圖中的Layer)包含了所有的資源文件和可執(zhí)行文件
Documents:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)會(huì)備份該目錄隘膘。例如疑故,游戲應(yīng)用可將游戲存檔保存在該目錄

tmp:保存應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù),使用完畢后再將相應(yīng)的文件從該目錄刪除弯菊。應(yīng)用沒(méi)有運(yùn)行時(shí)纵势,系統(tǒng)也可能會(huì)清除該目錄下的文件。iTunes同步設(shè)備時(shí)不會(huì)備份該目錄

Library/Caches:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)不會(huì)備份該目錄钦铁。一般存儲(chǔ)體積大扫茅、不需要備份的非重要數(shù)據(jù)

Library/Preference:保存應(yīng)用的所有偏好設(shè)置,NSUserDefaults的數(shù)據(jù)存放于此目錄下,iOS的Settings(設(shè)置)應(yīng)用會(huì)在該目錄中查找應(yīng)用的設(shè)置信息育瓜。iTunes同步設(shè)備時(shí)會(huì)備份該目錄

4葫隙、plist文件

1.plist存儲(chǔ),生成一個(gè)plist文件.
2.plist不是數(shù)組就是字典,plist存儲(chǔ)就是用來(lái)存儲(chǔ)字典或者數(shù)組.
注意:Plist不能存儲(chǔ)自定義對(duì)象

5、應(yīng)用沙盒目錄的常見獲取方式

// 獲取沙盒路徑

  • 1躏仇、NSHomeDirectory()

  • 2恋脚、tmp:NSString *tmp = NSTemporaryDirectory();

  • 3、Library/Caches:(跟Documents類似的2種方法)
    利用沙盒根目錄拼接”Caches”字符串
    利用NSSearchPathForDirectoriesInDomains函數(shù)(將函數(shù)的參數(shù)改為:NSCachesDirectory即可)

// directory:獲取哪個(gè)文件夾
    // domainMask:在哪個(gè)范圍內(nèi)搜索,NSUserDomainMask:表示在用戶的手機(jī)上查找
    // expandTilde:是否展開全路徑 YES:表示展開全路徑 NO:不會(huì)展開全路徑,會(huì)把應(yīng)用沙盒的路徑用波浪號(hào)(~)代替
    // 獲取到Caches文件夾路徑
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    
    // 拼接文件名
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"arr.plist"];
    
    // 1焰手、存儲(chǔ)plist,File:文件的全路徑
    [arr writeToFile:filePath atomically:YES];
    // 2糟描、讀取plist,之前是什么類型存儲(chǔ)的,讀取也是什么
    NSArray *arr = [NSArray arrayWithContentsOfFile:filePath];
  • 4、Library/Preference:通過(guò)NSUserDefaults類存取該目錄下的設(shè)置信息

  • 6书妻、屬性列表
    屬性列表是一種XML格式的文件船响,拓展名為plist
    如果對(duì)象是NSString、NSDictionary躲履、NSArray见间、NSData、NSNumber等類型工猜,就可以使用writeToFile:atomically:方法直接將對(duì)象寫到屬性列表文件中

  • 7米诉、屬性列表-歸檔NSDictionary
    將一個(gè)NSDictionary對(duì)象歸檔到一個(gè)plist屬性列表中

// 將數(shù)據(jù)封裝成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"母雞" forKey:@"name"];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 將字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
image
image
  • 8、屬性列表-恢復(fù)NSDictionary

讀取屬性列表篷帅,恢復(fù)NSDictionary對(duì)象

image
image.png
  • 9史侣、偏好設(shè)置
    很多iOS應(yīng)用都支持偏好設(shè)置,比如保存用戶名魏身、密碼惊橱、字體大小等設(shè)置,iOS提供了一套標(biāo)準(zhǔn)的解決方案來(lái)為應(yīng)用加入偏好設(shè)置功能
    每個(gè)應(yīng)用都有個(gè)NSUserDefaults實(shí)例箭昵,通過(guò)它來(lái)存取偏好設(shè)置
    比如税朴,保存用戶名、字體大小宙枷、是否自動(dòng)登錄
    以字典的形式進(jìn)行偏好設(shè)置,用法跟字典一樣.
    偏好設(shè)置好處: 1.不需要關(guān)心文件名 2.快速進(jìn)行鍵值對(duì)存儲(chǔ) 3.直接存儲(chǔ)基本數(shù)據(jù)類型

保存:

// 獲取單例
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // @"123" key:pwd
    [defaults setObject:@"123" forKey:@"pwd"];
    
    // bool
    [defaults setBool:YES forKey:@"isOn"];
    
    // int
    [defaults setInteger:10 forKey:@"num"];

讀取也很簡(jiǎn)單

// 利用NSUserDefaults單例
   NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"pwd"];
   NSInteger i = [[NSUserDefaults standardUserDefaults] integerForKey:@"num"];
  • 10掉房、NSData
    使用archiveRootObject:toFile:方法可以將一個(gè)對(duì)象直接寫入到一個(gè)文件中,但有時(shí)候可能想將多個(gè)對(duì)象寫入到同一個(gè)文件中慰丛,那么就要使用NSData來(lái)進(jìn)行歸檔對(duì)象
    NSData可以為一些數(shù)據(jù)提供臨時(shí)存儲(chǔ)空間,以便隨后寫入文件瘾杭,或者存放從磁盤讀取的文件內(nèi)容诅病。可以使用[NSMutableData data]創(chuàng)建可變數(shù)據(jù)空間
    (圖)

1)NSData-歸檔2個(gè)Person對(duì)象到同一文件中

歸檔(編碼)

// 新建一塊可變數(shù)據(jù)區(qū)
NSMutableData *data = [NSMutableData data];
// 將數(shù)據(jù)區(qū)連接到一個(gè)NSKeyedArchiver對(duì)象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
// 開始存檔對(duì)象,存檔的數(shù)據(jù)都會(huì)存儲(chǔ)到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存檔完畢(一定要調(diào)用這個(gè)方法)
[archiver finishEncoding];
// 將存檔的數(shù)據(jù)寫入文件
[data writeToFile:path atomically:YES];

2)NSData-從同一文件中恢復(fù)2個(gè)Person對(duì)象

恢復(fù)(解碼)

// 從文件中讀取數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfFile:path];
// 根據(jù)數(shù)據(jù)贤笆,解析成一個(gè)NSKeyedUnarchiver對(duì)象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢復(fù)完畢
[unarchiver finishDecoding];

3)利用歸檔實(shí)現(xiàn)深復(fù)制
比如對(duì)一個(gè)Person對(duì)象進(jìn)行深復(fù)制

// 臨時(shí)存儲(chǔ)person1的數(shù)據(jù)
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
// 解析data蝇棉,生成一個(gè)新的Person對(duì)象
Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 分別打印內(nèi)存地址
NSLog(@"person1:0x%x", person1); // person1:0x7177a60
NSLog(@"person2:0x%x", person2); // person2:0x7177cf0

歸檔:
存儲(chǔ)自定義對(duì)象

Person *p = [[Person alloc] init];
    p.age = 18;   
    p.name = @"a";  
    // 獲取tem文件夾路徑
    NSString *tempPath = NSTemporaryDirectory();
    // 拼接文件名
   NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
    // NSKeyedArchiver專門用來(lái)做自定義對(duì)象歸檔
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];

在person.m

// 什么時(shí)候調(diào)用:當(dāng)一個(gè)對(duì)象要?dú)w檔的時(shí)候就會(huì)調(diào)用這個(gè)方法歸檔
// 作用:告訴蘋果當(dāng)前對(duì)象中哪些屬性需要?dú)w檔
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInt:_age forKey:@"age"];
}

解檔:

// 獲取tem文件夾路徑
    NSString *tempPath = NSTemporaryDirectory();
    
    // 拼接文件名
    NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
   // 解檔
   Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

什么時(shí)候調(diào)用:當(dāng)一個(gè)對(duì)象要解檔的時(shí)候就會(huì)調(diào)用這個(gè)方法解檔

// 作用:告訴蘋果當(dāng)前對(duì)象中哪些屬性需要解檔
// initWithCoder什么時(shí)候調(diào)用:只要解析一個(gè)文件的時(shí)候就會(huì)調(diào)用
- (id)initWithCoder:(NSCoder *)aDecoder
{
    #warning  [super initWithCoder]
    // 這里不能用[super initWithCoder],什么時(shí)候調(diào)用[super initWithCoder:aDecoder]:只要父類遵守了NSCoding協(xié)議,就調(diào)用
    if (self = [super init]) {
        // 解檔
        // 注意一定要記得給成員屬性賦值
      _name = [aDecoder decodeObjectForKey:@"name"];
      _age = [aDecoder decodeIntForKey:@"age"];
    }
    return self;
}

11.數(shù)據(jù)存儲(chǔ)(數(shù)據(jù)持久化)
1> 介紹iOS數(shù)據(jù)存儲(chǔ)的5種方式
2> 介紹應(yīng)用沙盒(應(yīng)用程序的文件夾)
? 如何找到應(yīng)用沙盒的路徑芥永?首先需要顯示隱藏文件篡殷。
? 點(diǎn)擊前往->個(gè)人->資源庫(kù)->Application Support->iPhone Simulator->7.1->里面全是應(yīng)用沙盒
3> 應(yīng)用沙盒怎么多文件夾保存,在哪個(gè)文件夾埋涧。介紹沙盒里的每一個(gè)文件夾板辽。

12.plist存儲(chǔ)
? 把一些系統(tǒng)自帶的OC對(duì)象生成pilst文件存儲(chǔ)起來(lái)。
1> 了解數(shù)據(jù)存儲(chǔ):數(shù)據(jù)存儲(chǔ)一般有兩個(gè)操作棘催,一個(gè)存劲弦,一個(gè)取。拖兩個(gè)按鈕醇坝,一個(gè)用來(lái)存邑跪,一個(gè)用來(lái)取
2> plist存儲(chǔ)原理:
? 只要有writeToFile的對(duì)象,就能進(jìn)行plist存儲(chǔ)呼猪,調(diào)用writeToFile就能自動(dòng)生成plist格式的文件画畅。
? 一般常用的Foundation對(duì)象都有這個(gè)方法,數(shù)組宋距,字典夜赵,字符串等
3> 如何寫入到沙盒,需要獲取沙盒路徑乡革。
? 獲取Documents路徑
? 拼接文件名寇僧,因?yàn)閿?shù)據(jù)是寫入到文件中,不是寫入到文件夾中沸版。路徑之間通過(guò)/分開的嘁傀,為了避免自己寫/,會(huì)用stringByAppendingPathCompent视粮,自動(dòng)在文件夾與文件之間添加/细办。
4> 如何讀取,存儲(chǔ)是什么類型存儲(chǔ)蕾殴,讀取出來(lái)也是什么類型笑撞,直接用存儲(chǔ)的類型,解析文件就好钓觉,用ContentsOfFile解析茴肥。
5> 注意plist存儲(chǔ),不能存儲(chǔ)自定義對(duì)象荡灾,會(huì)失敗的瓤狐。

13> 偏好設(shè)置
1> 什么是偏好設(shè)置存儲(chǔ):就是保存一些基本的信息瞬铸,賬號(hào),密碼础锐,狀態(tài)嗓节。
2> 偏好設(shè)置原理:不需要關(guān)心文件名,直接通過(guò)NSUserDefaults操作皆警,默認(rèn)就存到偏好設(shè)置里面了拦宣。
? 通過(guò)NSUserDefaults就能直接訪問(wèn)軟件的偏好設(shè)置(Library/Preferences)
3> 怎么利用偏好設(shè)置存儲(chǔ)?利用NSUserDefaults調(diào)用setObject:forKey存儲(chǔ)。
? 偏好設(shè)置底層實(shí)現(xiàn)原理:底層其實(shí)就是利用一個(gè)字典信姓,存儲(chǔ)一些鍵值對(duì)鸵隧。
? 偏好設(shè)置好處:能快速存儲(chǔ)一些鍵值對(duì),如果用字典去存儲(chǔ)财破,還需要獲取文件名比較麻煩掰派。
? 偏好設(shè)置壞處:不能及時(shí)存儲(chǔ),需要做同步操作左痢,把內(nèi)存中的數(shù)據(jù)同步到硬盤上靡羡。
4> 怎么利用偏好設(shè)置讀取?和字典一樣,根據(jù)剛剛存儲(chǔ)的Key讀取俊性。

14> 自定義對(duì)象歸檔(歸檔:數(shù)據(jù)存儲(chǔ))
1> 自定義對(duì)象如何歸檔:用NSKeyedArchiver,調(diào)用archiveRootObject:toFile:方法略步,需要傳一個(gè)對(duì)象,自定義一個(gè)對(duì)象定页,傳進(jìn)去趟薄。
? 會(huì)報(bào)錯(cuò),說(shuō)對(duì)象沒(méi)有encodeWithCoder方法,說(shuō)明歸檔的時(shí)候默認(rèn)會(huì)調(diào)用這個(gè)方法典徊,去實(shí)現(xiàn)這個(gè)方法杭煎。
? 默認(rèn)打不出encodeWithCoder,必須遵守NSCoding協(xié)議才能實(shí)現(xiàn)這個(gè)方法卒落。
? encodeWithCoder什么時(shí)候調(diào)用:對(duì)象歸檔時(shí)候調(diào)用
? encodeWithCoder作用:告訴系統(tǒng)對(duì)象里的哪些屬性需要?dú)w檔羡铲,怎么去歸檔,根據(jù)一個(gè)key去歸檔儡毕,目的就是以后取的時(shí)候也切,也根據(jù)這個(gè)key去取數(shù)據(jù)。
2> 自定義對(duì)象如何解檔:用NSKeyedUnarchiver,調(diào)用unarchiveObjectWithFile方法腰湾,需要傳一個(gè)文件名雷恃。
? 會(huì)報(bào)錯(cuò),說(shuō)對(duì)象沒(méi)有initWithCoder方法,說(shuō)明解檔的時(shí)候默認(rèn)會(huì)調(diào)用這個(gè)方法费坊,去實(shí)現(xiàn)這個(gè)方法倒槐。
? initWithCoder什么時(shí)候調(diào)用:對(duì)象解檔時(shí)候調(diào)用
? initWithCoder作用:告訴系統(tǒng)對(duì)象里的哪些屬性需要解檔,怎么去解檔葵萎,根據(jù)之前存儲(chǔ)的key去解檔
? initWithCoder是一個(gè)初始化方法导犹,需要先初始化父類的唱凯,但是不能調(diào)用[super initWithCoder:],因?yàn)楦割怤SObject沒(méi)有遵守NSCoding協(xié)議羡忘。
3> initWithCoder什么時(shí)候需要調(diào)用[super initWithCoder:]
? initWithCoder原理:只要解析文件就會(huì)調(diào)用谎痢,xib,storyboard都是文件,因此只要解析這兩個(gè)文件卷雕,就會(huì)調(diào)用initWithCoder节猿。
? 因此如果在storyboard使用自定義view,重寫initWithCoder方法,一定要調(diào)用[super initWithCoder:]漫雕,因?yàn)橹挥邢到y(tǒng)才知道怎么解析storyboard滨嘱,如果沒(méi)有調(diào)用,就解析不了這個(gè)文件浸间。


轉(zhuǎn)載: iOS開發(fā)——UI進(jìn)階篇(十一)應(yīng)用沙盒太雨,歸檔,解檔魁蒜,偏好設(shè)置囊扳,plist存儲(chǔ),NSData兜看,自定義對(duì)象歸檔解檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锥咸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子细移,更是在濱河造成了極大的恐慌搏予,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弧轧,死亡現(xiàn)場(chǎng)離奇詭異雪侥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)精绎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門速缨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捺典,你說(shuō)我怎么就攤上這事鸟廓。” “怎么了襟己?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵引谜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我擎浴,道長(zhǎng)员咽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任贮预,我火速辦了婚禮贝室,結(jié)果婚禮上契讲,老公的妹妹穿的比我還像新娘。我一直安慰自己滑频,他們只是感情好捡偏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峡迷,像睡著了一般银伟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绘搞,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天彤避,我揣著相機(jī)與錄音,去河邊找鬼夯辖。 笑死琉预,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒿褂。 我是一名探鬼主播圆米,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贮缅!你這毒婦竟也來(lái)了榨咐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谴供,失蹤者是張志新(化名)和其女友劉穎块茁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桂肌,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡数焊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崎场。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佩耳。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谭跨,靈堂內(nèi)的尸體忽然破棺而出干厚,到底是詐尸還是另有隱情,我是刑警寧澤螃宙,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布蛮瞄,位于F島的核電站,受9級(jí)特大地震影響谆扎,放射性物質(zhì)發(fā)生泄漏挂捅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一堂湖、第九天 我趴在偏房一處隱蔽的房頂上張望闲先。 院中可真熱鬧状土,春花似錦、人聲如沸伺糠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)退盯。三九已至彼乌,卻和暖如春泻肯,著一層夾襖步出監(jiān)牢的瞬間渊迁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工灶挟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琉朽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓稚铣,卻偏偏與公主長(zhǎng)得像箱叁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惕医,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容