1梦鉴、對(duì)象歸檔
所謂對(duì)象歸檔集绰,類(lèi)似于“序列化”機(jī)制,歸檔就是用某種格式把一個(gè)或多 個(gè)對(duì)象保存到指定文件中,方便以后從文件中恢復(fù)他們嚼贡。
1.1 使用NSKeyedArchiver歸檔
NSKeyedArchiver和NSKeyedUnarchiver
對(duì)系統(tǒng)類(lèi)型直接歸檔
archiveRootObject: toFile:
unarchiveObjectWithFile:
//對(duì)象歸檔
- (void)test5{
//第一種方法队询,直接調(diào)用NSKeyedArchiver
//先創(chuàng)建一個(gè)NSDictionary對(duì)象
NSDictionary *dict = @{
@"Objective-C" : @89,
@"Rubby" : @69,
@"Python" : @75,
@"Perl" : @109
};
// 對(duì)dict對(duì)象進(jìn)行歸檔
NSString *filePath = @"/Users/lwg/Desktop/SettingBundle/SettingBundle/dict.archive";
[NSKeyedArchiver archiveRootObject:dict toFile:filePath];
// 讀取dict.archive
NSDictionary *dict1 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"%@",dict1);
}
1.2 實(shí)現(xiàn)NSCoding協(xié)議
一般來(lái)說(shuō),如果對(duì)象的實(shí)例變量是OC基本類(lèi)型,并且實(shí)現(xiàn)了NSCoding協(xié)議,則可直接調(diào)用encodingObject:forKey:方法來(lái)歸檔該實(shí)例變量,使用decodeObjectForKey:方法恢復(fù)該實(shí)例變量即可擎厢。
如果需要?dú)w檔、恢復(fù)任意自定義類(lèi)的實(shí)例辣吃,那么該類(lèi)型應(yīng)該實(shí)現(xiàn)NSCoding協(xié)議如下兩個(gè)方法:
initWithCoder:
encodeWithCoder:
@interface FKApple : NSObject<NSCoding>
@property (nonatomic,copy) NSString *color;
@property (nonatomic,assign) double weight;
@property (nonatomic,assign) int size;
- (id)initWithColor:(NSString *)color weight:(double)weight size:(int)size;
@end
方法實(shí)現(xiàn)
- (void)encodeWithCoder:(NSCoder *)aCoder{
//調(diào)用NSCoder的方法歸檔該對(duì)象的每個(gè)實(shí)例變量
[aCoder encodeObject:_color forKey:@"color"];
[aCoder encodeDouble:_weight forKey:@"weight"];
[aCoder encodeInt:_size forKey:@"size"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
// 使用NSCoder恢復(fù)color动遭、weight、size這3個(gè)key
// 所對(duì)應(yīng)的value神得,并將恢復(fù)的value賦給當(dāng)前對(duì)象的3個(gè)實(shí)例變量
_color = [aDecoder decodeObjectForKey:@"color"];
_weight = [aDecoder decodeDoubleForKey:@"weight"];
_size = [aDecoder decodeIntForKey:@"size"];
return self;
}
1.3使用NSData完成自定義歸檔
上面的方法每次只能將單個(gè)對(duì)象作為root進(jìn)行歸檔或者恢復(fù)厘惦,如果希望一次性收集多個(gè)對(duì)象,并進(jìn)行歸檔到單個(gè)文件中哩簿,可以使用NSMutableData來(lái)創(chuàng)建NSKeyedArchiver和NSKeyedUnarchiver對(duì)象宵蕉。
步驟如下:
1.以NSMutableData作為參數(shù),創(chuàng)建NSKeyedArchiver對(duì)象节榜;
2.重復(fù)調(diào)用NSKeyedArchiver對(duì)象的encodeObject:forKey:方法來(lái)歸檔所有需要?dú)w檔到一個(gè)文件中的對(duì)象羡玛。
3.調(diào)用NSKeyedArchiver對(duì)象的finishEncoding方法結(jié)束歸檔;
4.根據(jù)需要宗苍,程序可以選擇將保存歸檔數(shù)據(jù)的NSData通過(guò)網(wǎng)絡(luò)傳輸或者輸出到磁盤(pán)文件上稼稿。
// 使用NSData完成自定義歸檔
// 一次性將多個(gè)對(duì)象歸檔到單個(gè)文件中
- (void)test6{
//先創(chuàng)建一個(gè)NSDictionary對(duì)象
NSDictionary *dict = @{
@"Objective-C" : @89,
@"Rubby" : @69,
@"Python" : @75,
@"Perl" : @109
};
// 創(chuàng)建一個(gè)NSSet對(duì)象
NSSet *set = [NSSet setWithObjects:@"ios",@"Java",@"OC", nil];
FKApple *apple = [[FKApple alloc] initWithColor:@"紅色" weight:3.4 size:20];
// 創(chuàng)建一個(gè)NSMutableData對(duì)象,用于保存歸檔數(shù)據(jù)
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 重復(fù)調(diào)用此方法
[arch encodeObject:dict forKey:@"dict"];
[arch encodeObject:set forKey:@"set"];
[arch encodeObject:apple forKey:@"apple"];
[arch finishEncoding];
// 程序?qū)SData緩存區(qū)保存的數(shù)據(jù)寫(xiě)入文件
NSString *filePath = @"/Users/lwg/Desktop/SettingBundle/SettingBundle/multi.archive";
if ([data writeToFile:filePath atomically:YES] == NO) {
NSLog(@"歸檔失敾淇摺让歼!");
}
// 讀取歸檔
NSData *data1 = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data1];
NSDictionary *dict1 = [unarch decodeObjectForKey:@"dict"];
NSSet *set1 = [unarch decodeObjectForKey:@"set"];
FKApple *apple1 = [unarch decodeObjectForKey:@"apple"];
[unarch finishDecoding];
NSLog(@"%@",dict1);
NSLog(@"%@",set1);
NSLog(@"%@",apple1);
}
1.4使用歸檔實(shí)現(xiàn)深復(fù)制
當(dāng)程序歸檔一個(gè)對(duì)象時(shí),系統(tǒng)會(huì)把該對(duì)象關(guān)聯(lián)的所有數(shù)據(jù)都轉(zhuǎn)化為字節(jié)數(shù)據(jù)挪钓;如果程序從這些字節(jié)數(shù)據(jù)中恢復(fù)該對(duì)象是越,恢復(fù)出來(lái)的對(duì)象與原對(duì)象完全相同耳舅,但沒(méi)有任何公用的部分碌上,這就實(shí)現(xiàn)了深復(fù)制倚评。
// 利用歸檔實(shí)現(xiàn)深復(fù)制
- (void)deepCopy{
NSDictionary *dict = @{
@"one" : [[FKApple alloc] initWithColor:@"紅色" weight:3.4 size:20],
@"two" : [[FKApple alloc] initWithColor:@"綠色" weight:2.8 size:14]
};
// 將歸檔對(duì)象的數(shù)據(jù)寫(xiě)入NSData
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
// 從NSData對(duì)象中恢復(fù)對(duì)象,這樣既可完成深復(fù)制
NSDictionary *dictCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 獲取復(fù)制后的對(duì)象
FKApple *app = [dictCopy objectForKey:@"one"];
// 修改對(duì)象屬性
[app setColor:@"紫色"];
// 獲取原始對(duì)象
FKApple *oneApp = [dict objectForKey:@"one"];
// 訪(fǎng)問(wèn)該對(duì)象顏色馏予,發(fā)現(xiàn)并沒(méi)有改變
NSLog(@"dict中key為one對(duì)應(yīng)的顏色為:%@,復(fù)制后的app顏色為:%@",oneApp.color,app.color);
}