第十五章文件加載與保存


Cocoa提供了Core Data,他能在後臺處理所有文件內容
Cocoa提供了兩個通用的文件處理類:屬性列表和對象編碼
一、屬性列表
在Cocoa中,有一類名爲屬性列表的對象,簡寫爲plist。
這些列表包含Cocoa操作的一組對象,Cocoa知道如何將他們保存到文件中並進行加載
屬性列表類包括:NSArray、NSDictionary、NSString、NSNumber、NSDate和NSData以及他們的變體

1.NSDate
NSDate是Cocoa中用於處理日期和時間的基礎類
[NSDate date]獲取當前的日期和時間,它是自動釋放對象

+dateWithTimeIntervalSinceNow:(NSTimeInterval *)獲取與當前時間相隔的時間差
NSTimeInterval是一個雙精度參數,表示以秒爲單位的時間間隔,正數爲將來的時間,負數爲過去的時間
舉例代碼:
NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)];

2.NSData
NSData類包含大量字節,可以獲得數據的長度和指向字節起始位置的指針
NSData是一個對象,適用於常規的內存管理行爲,可以寫成自動釋放對象
NSData是不可改變的,被創建後就不能改變,可以使用但不能更改其中內容
NSMutableData支持在數據內容中添加和刪除字節
舉例代碼:
NSData *data =[NSData dataWithBytes:string
                      length:strlen(string)+1];

3.寫入和讀取屬性列表
(1)寫入
集合屬性列表類(NSArray、NSDictionary)具有一個-writeToFile:atomically;方法用於將屬性列表寫入文件
NSString和NSData也具有writeToFile:atomically方法,但只能寫出字符串或數據塊,所以可以寫入數組然後再保存數組
舉例代碼:

NSArray *phrase;

phrase = [NSArray arrayWithObjects:@"I",@"AM",@"DE",@"WEI",@"I'M ",@"29",@"YEARS",@"OLD",nil];

[phrase writeToFile:@"/tmp/xxxxx.plist" atomically:YES];

Tip:atomically爲YES時保存過程中會佔用雙倍的硬盤空間來保存文件

執行後會生成plist文件,可以使用Xcode自帶的屬性列表編輯器編輯
有些plist文件是以二進制壓縮保存的,可以使用plutil -convert xml1 filename.plist轉換一下再閱讀

(2)讀取
使用-arrayWithContentsOfFile方法讀取文件(因爲只能用數組保存所以返回的也會是數組)
舉例代碼:

NSArray *phrase = [NSArray arrayWithContentsOfFile:@"tmp/xxx.plist"];

NSLog(@"%@",phrase);

(3)最簡單的保存
可使用NSData的writeToFile:atomically轉換
不過這個方法不返回任何錯誤信息,如果不能加載文件只能得到nil指針,不能確定出現了何種錯誤

二、編碼對象
將對象自身的實例變量和其他數據編碼爲數據塊保存到磁盤,或者將數據塊度回到內存並基於數據創建新對象,稱爲序列化和反序列化 等價於 編碼和解碼

對於任何Objective-C都是用encodeObject:forKey;進行編碼
恢復某個對象,可以使用decodeSomethingForKey方法


如果對象不是屬性列表類型,則採用NSCoding協議和實現方法來編碼和解碼對象
採用NSCoding協議意味着必須實現encodeWithCoder和initWithCoder方法
舉例代碼:

#import <Foundation/Foundation.h>

@interface Thingie : NSObject <NSCoding> {

    NSString *name;

    int magicNumber;

    float shoeSize;

    NSMutableArray *subThingies;

}

@property (copy) NSString *name;

@property intmagicNumber;

@property float shoeSize;

@property (retain) NSMutableArray *subThingies;

- (id)initWithName: (NSString *) n

       magicNumber: (int) mn 

          shoeSize: (float) ss;

@end // Thingie



@implementationThingie

@synthesize name;

@synthesizemagicNumber;

@synthesize shoeSize;

@synthesizesubThingies;

- (id)initWithName: (NSString *) n

       magicNumber: (int) mn 

          shoeSize: (float) ss {

    if (self = [super init]) {

        self.name = n;

        self.magicNumber = mn;

        self.shoeSize = ss;

        self.subThingies = [NSMutableArray array];

    }

    return (self);

}

- (void) dealloc {

    [name release];

    [subThingies release];

    [super dealloc];

} // dealloc

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

    [coder encodeObject: name

           forKey: @"name"];

    [coder encodeInt: magicNumber

           forKey: @"magicNumber"];

    [coder encodeFloat: shoeSize

           forKey: @"shoeSize"];

    [coder encodeObject: subThingies

           forKey: @"subThingies"];

} // encodeWithCoder

- (id) initWithCoder: (NSCoder *) decoder {

    if (self = [super init]) {

        self.name = [decoder decodeObjectForKey: @"name"];

        self.magicNumber = [decoder decodeIntForKey: @"magicNumber"];

        self.shoeSize = [decoder decodeFloatForKey: @"shoeSize"];

        self.subThingies = [decoder decodeObjectForKey: @"subThingies"];

    }

    return (self);

} // initWithCoder

- (NSString *) description {

    NSString*description =

    [NSString stringWithFormat: @"%@: %d/%.1f %@",

     name, magicNumber, shoeSize, subThingies];

    return(description);

} // description

@end // Thingie




使用NSKeyArchiver把對象歸檔到NSData中,
                keyedArchiver使用鍵/值對保存對象的信息

                                     archivedDataWithRootObject方法,先在後臺創建一個NSKeyedArchiver實例,然後將實例傳遞給-encodeWithCoder

                方法,方法複製自身屬性時,可以對其他對象也進行編碼

發佈了0 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章