Object 保存到文件中
6月4日?Object 保存到文件中
?Q、 你添加一個(gè)新類到你的項(xiàng)目當(dāng)中且你希望可以保存這個(gè)類的一個(gè)實(shí)例對象到磁盤文件 并在需要時(shí)從磁盤文件讀回到內(nèi)存中
?A、 方案
?確保你的類遵循 NSCoding 協(xié)議且在類中實(shí)現(xiàn)了需要是實(shí)現(xiàn)的方法.不要擔(dān)心,在本節(jié) 的討論部分我會帶著你學(xué)習(xí).
?D、 討論
?在 IOS SDK 中有兩個(gè)非常方便類來達(dá)到這個(gè)目的,在程序開發(fā)的術(shù)語中叫做編組,他們 是:
?NSKeyedArchiver 一個(gè)利用鍵值來歸檔或存儲對象或?qū)ο髽涞念?對象的每一個(gè)值,我們稱為屬性,
?都能使用程序員選定的鍵值來歸檔.你將獲得一個(gè)歸檔文件,讓后你將可以保存你的
?數(shù)值通過所選定頂?shù)逆I值,此很像一個(gè)字典. NSKeyedUnarchiver
?此類進(jìn)行與歸檔類相反的操作.它能很簡單地給你未歸檔的字典并要求你讀取值到 屬性中.
?為了讓歸檔及反歸檔工作正常,你需要確保需要?dú)w檔及反歸檔的對象遵循 NSCoding 協(xié) 議.讓我們以一個(gè)簡單的 Person 類開始,如下是這個(gè)類的頭文件:
@interface Person : NSObject<NSCoding>
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@end
 
 
如果現(xiàn)在你不寫此類的任何實(shí)現(xiàn)代碼且進(jìn)行編譯,你將會考到編譯器拋出的警告,說你 沒有遵循NSCoding協(xié)議且沒有實(shí)現(xiàn)需要實(shí)現(xiàn)的方法.需要實(shí)現(xiàn)的方法如下:
?- (void)encodeWithCoder:(NSCoder *)aCoder 此方法將給你一個(gè)編碼器對象.此編碼器對象你可以像一個(gè)詞典那樣使用,可以簡單的通過你所選擇的鍵值 存儲數(shù)值進(jìn)去.
?- (id)initWithCoder:(NSCoder *)aDecoder; 當(dāng)你使用NSKeyedUnarchiver對象反歸檔你的對象時(shí),此方法將被調(diào)用.你可以很簡單的通過傳遞進(jìn)來的 NSCoder對象獲取你回的數(shù)值
?現(xiàn)在,基于上面的信息,我們實(shí)現(xiàn)我們的類:
 
#import "Person.h"
 
NSString *const kFirstNameKey = @"FirstNameKey";
NSString *const kLastNameKey = @"LastNameKey";
 
@implementation Person
 
 
-(void)encodeWithCoder:(NSCoder *)aCoder
{
? ? [aCoder encodeObject:self.firstName forKey:kFirstNameKey];
? ? [aCoder encodeObject:self.lastName forKey:kLastNameKey];
}
 
-(id)initWithCoder:(NSCoder *)aDecoder
{
? ? self = [super init];
? ? if (self != nil) {
? ? ? ? _firstName = [aDecoder decodeObjectForKey:kFirstNameKey];
? ? ? ? _lastName = [aDecoder decodeObjectForKey:kLastNameKey];
? ? }
? ? return self;
}
 
 
@end
 
NSString *const kFirstName = @"Steven";
NSString *const kLastName = @"Jobs";
 
/* Determine where we want to archive the object */
? ? NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"steveJobs"];
? ? /* Instantiate the object */
? ? Person *steveJobs = [[Person alloc] init];
? ? steveJobs.firstName = kFirstName;
? ? steveJobs.lastName = kLastName;
? ? /* Archive the object to the file */
?? NSData *data= [NSKeyedArchiver archivedDataWithRootObject:steveJobs];
? ? [data writeToFile:filePath atomically:YES];
?? ?
? ? NSData *readData = [NSData dataWithContentsOfFile:filePath];
?? Person *cloneOfSteveJobs = [NSKeyedUnarchiver unarchiveObjectWithData:readData];
?? ?
?? ?
? ? if ([cloneOfSteveJobs.firstName isEqualToString:kFirstName] &&
? ? ? ? [cloneOfSteveJobs.lastName isEqualToString:kLastName]){
? ? ? ? NSLog(@"Unarchiving worked"); } else {
? ? ? ? ? ? NSLog(@"Could not read the same values back. Oh no!");
? ? ? ? }
 
 
或者這樣
 
/* Determine where we want to archive the object */
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"steveJobs.txt"];
/* Instantiate the object */
Person *steveJobs = [[Person alloc] init];
steveJobs.firstName = kFirstName;
steveJobs.lastName = kLastName;
/* Archive the object to the file */
[NSKeyedArchiver archiveRootObject:steveJobs toFile:filePath];
/* Now unarchive the same class into another object */
Person *cloneOfSteveJobs =
[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
/* Check if the unarchived object has the same first name and last name as the previously archived object */
if ([cloneOfSteveJobs.firstName isEqualToString:kFirstName] &&
? ? [cloneOfSteveJobs.lastName isEqualToString:kLastName]){
? ? NSLog(@"Unarchiving worked"); } else {
? ? ? ? NSLog(@"Could not read the same values back. Oh no!");
? ? }
總結(jié)
以上是生活随笔為你收集整理的Object 保存到文件中的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 6月19日 NSFileHandle文件
 - 下一篇: TP5 数据库迁移工具 migrate