iOS的數(shù)據(jù)存儲

背景

在iOS開發(fā)中必不可少的要用到數(shù)據(jù)存儲,數(shù)據(jù)的處理是iOS開發(fā)中的核心技術(shù)娃磺,適當?shù)膶?shù)據(jù)進行持久化存儲可以實現(xiàn)應(yīng)用的離線功能薄湿,以此提高用戶體驗。所謂數(shù)據(jù)持久化偷卧,就是將數(shù)據(jù)保存到硬盤中豺瘤,使得在應(yīng)用程序或手機重啟后可以繼續(xù)訪問之前保存的數(shù)據(jù)。在iOS開發(fā)中听诸,有很多持久化得方案坐求,接下來我將總結(jié)以下5種持久化方案:
1、plist(屬性列表)
2晌梨、preference(偏好設(shè)置)
3桥嗤、NSKeyedArchiver(歸檔)
4、SQList 3 (FMDB)
5仔蝌、CoreData

應(yīng)用沙盒

在介紹各種存儲方法之前泛领,先說明下沙盒機制。每個iOS應(yīng)用都有一個 應(yīng)用沙盒「文件系統(tǒng)目錄」敛惊,與其他文件系統(tǒng)隔離
應(yīng)用必須在自己的沙盒里渊鞋,其他應(yīng)用不能訪問他人的沙盒

EAA11FC5-13D8-41A6-AF51-83FFE21E3808.png
  • Documents:保存應(yīng)用運行時生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時會備份該目錄瞧挤。例如锡宋,游戲應(yīng)用可將游戲存檔保存在該目錄

  • tmp:保存應(yīng)用運行時所需的臨時數(shù)據(jù),使用完畢后再將相應(yīng)的文件從該目錄刪除皿伺。應(yīng)用沒有運行時员辩,系統(tǒng)也可能會清除該目錄下的文件盒粮。iTunes同步設(shè)備時不會備份該目錄

  • Library/Caches:保存應(yīng)用運行時生成的需要持久化的數(shù)據(jù)鸵鸥,iTunes同步設(shè)備時不會備份該目錄。一般存儲體積大丹皱、不需要備份的非重要數(shù)據(jù)

  • Library/Preference:保存應(yīng)用的所有偏好設(shè)置妒穴,iOS的Settings(設(shè)置)應(yīng)用會在該目錄中查找應(yīng)用的設(shè)置信息。iTunes同步設(shè)備時會備份該目錄


    // 獲取 Documents 文件路徑
    // 方法一摊崭、利用沙盒根目錄拼接 ”Documents” 字符串
    // 不建議采用讼油,因為新版本的操作系統(tǒng)可能會修改目錄名
    NSString *home = NSHomeDirectory();
    NSString *documents = [home stringByAppendingPathComponent:@"Documents"];

// 方法二、利用 NSSearchPathForDirectoriesInDomains 函數(shù)
    
    /**
     NSSearchPathForDirectoriesInDomains

     @param NSDocumentDirectory 搜索目錄是呢簸,Documents 目錄
     @param NSUserDomainMask 搜索范圍是矮台,用戶文件夾
     @param NO 不展開全路徑:~/Library/Caches
     @return NSArray*
     */
    
    NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
    NSLog(@"libraryPath = %@",libraryPath);
    
    NSString *preferencePath =[libraryPath stringByAppendingString:@"/preferences"];
    NSLog(@"%@",preferencePath);
    
    
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
    NSLog(@"cachesPath = %@",cachesPath);

    // 獲取 tmp 文件路徑
    NSString *tmpPath = NSTemporaryDirectory();


plist(屬性列表)

iOS提供了一種plist格式的文件(屬性列表)用于存儲輕量級的數(shù)據(jù)乏屯,屬性列表是一種XML格式的文件,拓展名為plist。如果對象是NSString瘦赫、NSDictionary辰晕、NSArray、NSData類型,就可以使用writeToFile:atomically:?法 直接將對象寫到屬性列表文件中該格式保存的數(shù)據(jù)可以直接使用NSDictionary和NSArray讀取 确虱。plist文件在iOS開發(fā)中屬于Write寫入方式含友,可以以Property List列表形式顯示,也可以以xml格式顯示校辩。對于數(shù)據(jù)管理是很方便的窘问。掌握使用plist文件數(shù)據(jù)操作很有必要.

  • NSString 寫入文件 讀取
 NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"str.txt"];
    NSString *str = @"這是一個字符串";
    //atomically是否進行線性操作(YES保證發(fā)生意外時有中轉(zhuǎn)文件來保存信息 直至寫入完成 但是損耗大. NO的時候?qū)懭胨俣瓤?但是沒有安全保障)
    [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    //2017-03-19 15:28:09.740 信號量[3255:166796] 這是一個字符串
    NSLog(@"%@",str1);

D2A41CA4-9724-414A-9CA1-8808E22778E5.png
  • NSArray 寫入文件 讀取
  NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"arr.txt"];
    NSArray *array = @[@"abc",@"def",@"ghi"];
    [array writeToFile:filePath atomically:YES];
    
    NSArray *getArray = [NSArray arrayWithContentsOfFile:filePath];
//    2017-03-19 15:34:52.261 信號量[3423:172597] (
//                                              abc,
//                                              def,
//                                              ghi
//                                              )
    NSLog(@"%@",getArray);

81CF3301-99E0-4F30-97B8-8FABADE86B14.png
  • NSDictionary 寫入文件 讀取
  NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"arr.txt"];
    NSDictionary *dic = @{@"name":@"jack",@"age":@"13"};
    [dic writeToFile:filePath atomically:YES];
    
    NSDictionary *mydic = [NSDictionary dictionaryWithContentsOfFile:filePath];
//    2017-03-19 15:39:03.598 信號量[3479:176290] {
//        age = 13;
//        name = jack;
//    }

    NSLog(@"%@",mydic);
    
2838F4E0-9011-432E-B103-5B45FFD5545B.png
  • NSData對象寫入 讀取
 NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"22.png"];
   
    UIImage *image = [UIImage imageNamed:@"22.png"];
    
    NSData *data = UIImagePNGRepresentation(image);
    
    [data writeToFile:filePath atomically:YES];
    
    NSData *myData = [NSData dataWithContentsOfFile:filePath];
    //2017-03-19 15:45:55.005 信號量[3666:183586] 3157
    NSLog(@"%lu",(unsigned long)myData.length);

75B9FBD2-6013-47E3-B489-C4D877CE79C0.png

preference(偏好設(shè)置)

使用NSUserDefault 實現(xiàn)持久化
下面來看下 NSUserDefault 本地保存的位置,Library/Preferences 這個目錄下的 plist 文件就是其保存的目錄宜咒。

  //1.獲得NSUserDefaults文件
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  //2.向文件中寫入內(nèi)容
  [userDefaults setObject:@"AAA" forKey:@"a"];
  [userDefaults setBool:YES forKey:@"sex"];
  [userDefaults setInteger:21 forKey:@"age"];
  //2.1立即同步
  [userDefaults synchronize];
  //3.讀取文件
  NSString *name = [userDefaults objectForKey:@"a"];
  BOOL sex = [userDefaults boolForKey:@"sex"];
  NSInteger age = [userDefaults integerForKey:@"age"];

881054C8-D179-4E02-AAF0-4AF35E1AB9EF.png

偏好設(shè)置是專門用來保存應(yīng)用程序的配置信息的惠赫,一般不要在偏好設(shè)置中保存其他數(shù)據(jù)。
如果沒有調(diào)用synchronize方法故黑,系統(tǒng)會根據(jù)I/O情況不定時刻地保存到文件中汉形。所以如果需要立即寫入文件的就必須調(diào)用synchronize方法。
偏好設(shè)置會將所有數(shù)據(jù)保存到同一個文件中倍阐。即preference目錄下的一個以此應(yīng)用包名來命名的plist文件概疆。

NSKeyedArchiver(歸檔)

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;

@end
#import "Person.h"
//遵守NSCoding協(xié)議
@interface Person()<NSCoding>


@end

@implementation Person

#pragma mark 編碼,對象屬性進行編碼
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    //前者(_age,_name)是屬性,后者是關(guān)鍵字Key(age,name)
    [aCoder encodeInt:_age forKey:@"age"];
    [aCoder encodeObject:_name forKey:@"name"];
}

#pragma mark 解碼,解碼歸檔數(shù)據(jù)初始化對象
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        _age = [aDecoder decodeIntForKey:@"age"];
        _name = [aDecoder decodeObjectForKey:@"name"];
    }
    return self;
}

@end

測試

  NSArray *documentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArray firstObject];
    NSLog(@"documentPath = %@",documentPath);
    
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"person"];
    
    
    Person *p = [Person new];
    p.name =@"wang";
    p.age = 12;
    //Encoding保存Person
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];
    
    Person *pp = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
//    2017-03-19 16:32:16.750 信號量[4359:217706] wang
//    2017-03-19 16:32:16.751 信號量[4359:217706] 12
    NSLog(@"%@",pp.name);
    NSLog(@"%d",pp.age);

SQList 3和CoreData下篇再寫

SQList 3封裝 http://www.reibang.com/p/5471d001572c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市峰搪,隨后出現(xiàn)的幾起案子岔冀,更是在濱河造成了極大的恐慌,老刑警劉巖概耻,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件使套,死亡現(xiàn)場離奇詭異,居然都是意外死亡鞠柄,警方通過查閱死者的電腦和手機侦高,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厌杜,“玉大人奉呛,你說我怎么就攤上這事『痪。” “怎么了瞧壮?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匙握。 經(jīng)常有香客問我咆槽,道長,這世上最難降的妖魔是什么圈纺? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任秦忿,我火速辦了婚禮麦射,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灯谣。我一直安慰自己法褥,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布酬屉。 她就那樣靜靜地躺著半等,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呐萨。 梳的紋絲不亂的頭發(fā)上杀饵,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音谬擦,去河邊找鬼切距。 笑死,一個胖子當著我的面吹牛惨远,可吹牛的內(nèi)容都是我干的谜悟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼北秽,長吁一口氣:“原來是場噩夢啊……” “哼葡幸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贺氓,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蔚叨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辙培,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔑水,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年扬蕊,在試婚紗的時候發(fā)現(xiàn)自己被綠了搀别。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡尾抑,死狀恐怖歇父,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛮穿,我是刑警寧澤庶骄,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站践磅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏灸异。R本人自食惡果不足惜府适,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一羔飞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧檐春,春花似錦逻淌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至俐巴,卻和暖如春骨望,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欣舵。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工擎鸠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缘圈。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓劣光,卻偏偏與公主長得像,于是被迫代替她去往敵國和親糟把。 傳聞我的和親對象是個殘疾皇子绢涡,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

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