天天看點

Object-C基礎(15)——NSBundle與對象歸檔

 NSBundle

      NSBundle:它也是用于進行資源通路的API,它主要用于通路項目内部的資源。

     開發了一個APP,遊戲,它們肯定會包含大量的資源:圖檔、音效、地圖檔案、模型檔案……

     對于這些資源的管理,肯定涉及如下問題:

     1. 如果使用絕對路徑來存放資源,當這個應用釋出到用戶端時,這些資源檔案如何保證也正确地安裝到了用戶端。

     2. 當程式通路這些資源時,怎麼保證這些資源也位于正确的位置。

     很多時候,會直接把一些應用常見的資源,直接打包在應用裡面。

     主流用法:

     (1)調用mainBundle方法來擷取NSBundle對象。

     (2)pathForResource:ofType或URLForResourceofType:使用NSBundle來擷取指定資源的Path或URL。

      (3) 拿到資源的Path或URL之後,程式即可通過該Path或URL來通路資源内容。

     NSBundle的主要作用是擷取指定資源的Path或URL,它并不能通路資源的内容。如果要通路内容,

     還是用之前介紹的,NSString、NSArray、NSDictionary、NSFileManager、NSFileHandle……這樣一些工具類。

對象歸檔

     對象,本來是儲存記憶體中的,具有瞬時性(瞬态) —— 當程式退出、機器斷電時,對象就會從記憶體中消失。

     有時候,程式需要把對象“永久”地儲存下來。是以需要把對象儲存到“硬碟”類似的實體儲存設備、甚至通過網絡傳輸。

     對象歸檔(序列化):

                  ------------->

     記憶體中對象           磁盤(網絡)上的資料

                 <-------------

      對象歸檔主要用到2個類:

     - NSKeyedArchiver:負責歸檔。  把對象轉化成磁盤或網絡上的資料。

     - NSKeyedUnarchiver:負責反歸檔。  把磁盤或網絡上的資料轉換成對象。

     使用NSKeyedArchiver歸檔:

      A。 直接調用+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path 或

                 + (NSData *)archivedDataWithRootObject:(id)rootObject

          方法進行歸檔。

          上面的第一個方法,直接将對象轉換成磁盤上的二進制資料。簡單、直覺。

          第二個方法,将對象轉換成記憶體中二進制資料(NSData),接下來即可把該資料通過網絡發送,也可儲存到磁盤上。

          通過A方式進行歸檔,會導緻記憶體中每個對象都會生成一份對應的二進制資料。

      B。 以指定NSMutableData為參數,建立NSKeyedArchiver。

          接下來程式依次通過NSKeyedArchiver對N個對象進行歸檔,所有對象,都會被歸檔到NSMutableData中,

          歸檔完成之後,調用NSKeyedArchiver的finishEncoding結束歸檔即可。所有對象資料都在NSMutableData中

     使用NSKeyedUnarchiver反歸檔:

         與歸檔時所采用的方式對應,如果歸檔時使用了A方式,此處也應該使用A方式進行反歸檔;

       如果歸檔時使用了B方式,此處也應該使用B方式進行反歸檔;

      A方式,每個資料中隻包含一個歸檔對象時,

            程式調用unarchiveObjectWithFile:或unarchiveObjectWithData:方法進行反歸檔。

      B方式,資料中包含多個歸檔對象時,

            程式調用unarchiveObjectWithFile:或unarchiveObjectWithData:方法進行反歸檔。

          以指定NSData為參數,建立NSKeyedUnarchiver。

          接下來程式依次通過NSKeyedUnarchiver對N個對象根據key進行反歸檔,所有對象,都會被歸檔到NSMutableData中,

          歸檔完成之後,調用NSKeyedArchiver的finishEncoding結束歸檔即可。所有對象資料都在NSMutableData中

      對于B種方式,歸檔和反歸檔的順序并不需要一緻——因為都是按歸檔對象的key來進行的。

      自定義類的歸檔

       如果一個類需要能被歸檔,該類必須滿足如下2個要求:

       - 遵守NSCoding協定。

       - 并實作NSCoding協定中2個方法。

         其中:- (void)encodeWithCoder: 負責将對象轉成二進制資料。

              調用NSCoder的encodeXxx:forKey:方法把對象狀态資訊轉成二級制資料即可。

              - (id)initWithCoder:(NSCoder*)decoder:負責把二進制資料恢複成對象的狀态。

              調用NSCoder的decodeXxx:forKey:方法把二級制資料轉成對象的狀态即可。

       【注意:】如果一個類要是可歸檔的,那麼該類的所有屬性的類型也必須是可歸檔。

                ——否則當你歸檔該對象時,那個不可被歸檔的屬性将會導緻錯誤。

        使用歸檔來實作深拷貝。

         源對象 —> 歸檔到NSData中 -> 從NSData中恢複,得到一個新對象。