歸檔

一、歸檔的基本概念

之前將數據保存本地,只能是字符串、數組、字典、NSNuber、BOOL等容器類對象對象,不能將所有對象都給保存,而采用歸檔能將所有的對象轉化為二進制數據保存在文件中,并通過解歸檔讓將文件里面保存的數據讀取出來

二、使用環境

之前我們給通訊錄添加一個聯系人只能是將添加的人放到一個字典中,然后將這個字典放到數組中,最終將數組寫入文件中

當我們需要顯示這些聯系人時,要從文件中將這個數組讀取出來,還要將數據里面的一個個字典轉化成model,放到一個新數組里

而現在我們可以使用歸檔在添加的時候就將這一個個聯系人的信息轉化成model,將這些model直接放到一個數組里,需要展示的時候,在從文件中讀取出來數據,此時這個數組里面存放直接就是一個個model

有些應用支持一個離線緩存,也就是說當手機沒聯網時,可以將手機有網時的數據存放在本地,當手機沒網時,從本地中取出來這些數據展示

三、某個對象支持歸檔解歸檔需要滿足三個條件

1、所屬的類遵守NSCoding協議

2、實現協議里面的歸檔方法

  - (void)encodeWithCoder:(NSCoder *)aCoder

3、實現協議里面的解歸檔方法

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

四、對系統的類進行歸檔解歸檔

1、指定將對象放在哪個文件中,歸檔后的文件,后綴要求是archiver

   [NSHomeDirectory() stringByAppendingPathComponent:@"data.archiver"];

2、將對象歸檔到指定的路徑中

   [NSKeyedArchiver archiveRootObject:name toFile:path];

3、將歸檔后的數據提取出來

   [NSKeyedUnarchiver unarchiveObjectWithFile:path];

五、對自定義的類進行歸檔與解歸檔

1、讓這個類遵循<NSCoding>

2、實現歸檔方法,aCoder就是歸檔時傳過來的歸檔對象,對象被歸檔時會調用這個方法

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

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

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

     [aCoder encodeObject:self.sex forKey:@"sex"];
  }


3、實現解歸檔方法,對象解歸檔是會調用這個方法

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

   //解歸檔時會產生一個Person對象,這里是給這個Person對象賦值
   self = [super init];
  
   if (self) {
    
     self.name = [aDecoder decodeObjectForKey:@"name"];

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

     self.sex = [aDecoder decodeObjectForKey:@"sex"];
   }

     return self;
 }

六、同時將多個對象歸檔與解歸檔

1、歸檔

  1)準備一個可變的data對象,通過歸檔對象將多個數據存在一個data對象里,最終將這個data寫入文件

    NSMutableData *data = [NSMutableData data];

  2)archiver初始化的時候包裝一個可變的data對象

    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];

  3)通過歸檔對象將這些數據轉化成二進制,并保存在一個data對象里

    [archiver encodeObject:name forKey:@"name"];

    [archiver encodeInteger:age forKey:@"age"];

    [archiver encodeObject:sex forKey:@"sex"];

  4)轉化完畢,意思是結束使用歸檔對象將上面的數據保存在了data里面

    [archiver finishEncoding];

  5)將轉化好的data寫入文件

    [data writeToFile:path atomically:YES];

2、解歸檔

  1)將路徑里的二進制數據給取出來
    
    NSMutableData *data = [NSMutableData dataWithContentsOfFile:path];

  2)將二進制數據包裝在一個解歸檔對象中

    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];

  3)通過解歸檔對象將二進制數據分別給反序列化

    NSString *name = [unarchiver decodeObjectForKey:@"name"];

    NSInteger age = [unarchiver decodeIntegerForKey:@"age"];

    NSString *sex = [unarchiver decodeObjectForKey:@"sex"];

七、練習

1、模擬網絡數據進行本地緩存

1)修改新工程自帶的ViewController.h 如下

   #import <UIKit/UIKit.h>

   @interface ViewController : UITableViewController

   @end

2)在AppDelegate.m里面自定義window,

   self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
   [self.window makeKeyAndVisible];
   //報錯后,記得導入ViewController  #import "ViewController.h"
   self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[[ViewController alloc]init]];

3)新建一個InfoModel類,

   InfoModel.h

    #import <Foundation/Foundation.h>

    //對象要歸檔必須要遵守NSCoding協議
    @interface InfoModel : NSObject<NSCoding>

    @property(nonatomic,copy) NSString *name;
    @property(nonatomic,copy) NSString *phone;

    @end

   InfoModel.m

   #import "InfoModel.h"

   @implementation InfoModel

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

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

    [aCoder encodeObject:self.phone forKey:@"phone"];
   }


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

    self = [super init];

    if (self) {
    
      self.name = [aDecoder decodeObjectForKey:@"name"];
    
      self.phone = [aDecoder decodeObjectForKey:@"phone"];
    }

    return self;

   }
   
   @end

4) ViewController.m

   #import "ViewController.h"

   #import "InfoModel.h"

   //報錯,將課件中的MJExtension文件夾拖到工程中
   #import "MJExtension.h"

   //模擬服務器路徑
   #define kLocalPath [NSHomeDirectory() stringByAppendingPathComponent:@"data.archiver"]

   //模擬本地緩存路徑
   #define kServerPath [[NSBundle mainBundle] pathForResource:@"Connect" ofType:@"plist"]


   @interface ViewController ()
   {
     NSMutableArray *dataArray;
   }
   @end

   @implementation ViewController

   - (void)viewDidLoad {
      [super viewDidLoad];

      [self loadData];
   }

   - (void)loadData{

       //準備數據
       dataArray = [self fetchData];


       if(dataArray == nil){
    
         NSLog(@"請檢查網絡設置");
    
         return;
       }

       [self.tableView reloadData];

   }

   - (NSMutableArray *)fetchData{

       //1、先從服務器獲取數據
       NSMutableArray *tempArray = [NSMutableArray arrayWithContentsOfFile:kServerPath];

       if (tempArray == nil) {
    
         //2、如果從服務器獲取數據失敗,則從本地緩存中讀取數據
         tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile:kLocalPath];

       }else{
   
        //3、如果從服務器獲取數據成功,則將數據通過MJExtension框架,轉化為model
        tempArray = [InfoModel mj_objectArrayWithKeyValuesArray:tempArray];
    
        //4、將最新從服務器獲取到數據保存到本地
        [NSKeyedArchiver archiveRootObject:tempArray toFile:kLocalPath];
   
       }

       return tempArray;

    }


   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

      return dataArray.count;
    }

   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

      static NSString *cellID = @"cellID";

      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

      if (cell == nil) {
    
      cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
      
      }


      InfoModel *model = dataArray[indexPath.row];

      cell.textLabel.text = model.name;

      cell.detailTextLabel.text = model.phone;

      return cell;

    }

   @end
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容

  • 一、歸檔的基本概念 之前將數據保存本地,只能是字符串、數組、字典、NSNuber、BOOL等容器類對象對象,不能將...
    空白Null閱讀 5,228評論 1 10
  • 一、歸檔介紹 1.歸檔是指用某種格式來保存一個或多個對象,以便以后還原這些對象的過程。歸檔是將數據持久化的一種方式...
    lilinjianshu閱讀 862評論 0 0
  • 歸檔 歸檔->數據持久化的方式->加密(把文件加密《不是把數據加密》 歸檔分為: 1、存儲數據(編碼、序列化、歸檔...
    磊CC閱讀 2,153評論 2 3
  • 一、歸檔的基本概念 之前將數據保存本地,只能是字符串、數組、字典、NSNuber、BOOL等容器類對象對象,不能將...
    Luyize閱讀 639評論 0 0
  • 關鍵詞: 歸檔:數據持久化的一種方式,是將數據進行編碼序列化之后存儲的過程。適用于小量數據的存儲。 解檔:對歸檔的...
    追沐閱讀 1,501評論 0 1