生活随笔
收集整理的這篇文章主要介紹了
OC学习篇之---归档和解挡
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今天我們來看一下OC中的一個重要知識點:歸檔
OC中的歸檔就是將對象寫入到一個文件中,Java中的ObjectInputStream和ObjectOutputStream來進行操作的。當然在操作的這些對象都是需要實現一個接口:Serializable,同樣的OC中操作的對象也是需要實現一個協議的,后面會說到。
?
一、已有類型的歸檔和解檔
首先來看一個簡單的例子:
?
[objc]?view plaincopy
??#import?<Foundation/Foundation.h>????int?main(int?argc,?const?charchar?*?argv[])?{??????@autoreleasepool?{????????????????????????????????????????????????????????????????????????????????????????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];??????????????????NSData?*data?=?[[NSData?alloc]?initWithContentsOfFile:filePath];????????????????????????????NSKeyedUnarchiver?*unarchiver?=?[[NSKeyedUnarchiver?alloc]?initForReadingWithData:data];????????????????????????????NSArray?*array?=?[unarchiver?decodeObjectForKey:@"array"];??????????NSLog(@"%@",array);????????????????????int?value?=?[unarchiver?decodeObjectForKey:@"scope"];??????????NSLog(@"%d",value);??????????????????????????????????????}??????return?0;??}?? ?
?
1、歸檔
?
[objc]?view plaincopy
?NSArray?*array?=?[NSArray?arrayWithObjects:@"zhang",@"wangwu",@"lisi",nil];???NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];??????BOOL?success?=?[NSKeyedArchiver?archiveRootObject:array?toFile:filePath];???if(success){???????NSLog(@"保存成功");???}?? 我們這里將一個NSArray對象寫入到一個文件中。
?
這里說到了創建一個文件的方法:
?
[objc]?view plaincopy
NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];?? ?
我們可以打印一下filePath的值:
NSHomeDirectory()返回的就是當前用戶路徑
我們查看一下array.src的內容:
我們看到內容是亂的,但是我們貌似還是能看到一點,比如wangwu/lisi等字眼,說明在歸檔的時候并沒有深入的加密。
2、解檔
?
[objc]?view plaincopy
NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];??id?array?=?[NSKeyedUnarchiver?unarchiveObjectWithFile:filePath];??NSLog(@"%@",array);?? 解檔也是很簡單的,就是返回一個對象,不過這里用了id類型的,因為讀出來也不確定是哪種類型的。
?
?
3、對多個對象進行歸檔到一個文件
?
[objc]?view plaincopy
?NSArray?*array?=?[NSArray?arrayWithObjects:@"zhangsan",@"lisi",?nil?nil];???NSMutableData?*data?=?[NSMutableData?data];???NSKeyedArchiver?*archiver?=?[[NSKeyedArchiver?alloc]?initForWritingWithMutableData:data];????[archiver?encodeObject:array?forKey:@"array"];???[archiver?encodeInt:100?forKey:@"scope"];???[archiver?encodeObject:@"jack"?forKey:@"name"];???????[archiver?finishEncoding];???[archiver?release];??????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];???BOOL?success?=?[data?writeToFile:filePath?atomically:YES];???if(success){???NSLog(@"歸檔成功");???}?? 多個對象歸檔的話,這里要用到一個類:NSMutableData和NSData,他們兩的區別很簡單,一個是可變的,一個是不可變的。然后這里還創建了一個歸檔器:NSKeyedArchiver,這個類負責進行指定類型的編碼操作,然后將數據填充到NSMutableData類。歸檔的時候對每個類型對象用一個key進行對應,這個NSData和NSDirctionary很類似了。
?
?
4、對多個對象進行解檔操作
?
[objc]?view plaincopy
NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];??NSData?*data?=?[[NSData?alloc]?initWithContentsOfFile:filePath];????NSKeyedUnarchiver?*unarchiver?=?[[NSKeyedUnarchiver?alloc]?initForReadingWithData:data];????NSArray?*array?=?[unarchiver?decodeObjectForKey:@"array"];??NSLog(@"%@",array);????int?value?=?[unarchiver?decodeObjectForKey:@"scope"];??NSLog(@"%d",value);?? 我們可以將文件解檔出一個NSData對象,然后可以通過key去獲取指定的類型對象
?
?
二、自定義類型的歸檔和解檔
上面說到了已有類型的歸檔和解檔,下面來看一下自定義類型的歸檔和解檔操作,在開始的時候也說了,如果自定義的類型可以進行歸檔和解檔的話,必須實現一個協議:NSCoding
不多說了,下面來直接看代碼解釋:
Person.h
?
[java]?view plaincopy
??#import?<Foundation/Foundation.h>????@interface?Person?:?NSObject<NSCoding>????@property(nonatomic,copy)NSString?*name;??@property(nonatomic,assign)NSInteger?age;??@property(nonatomic,retain)NSArray?*apples;????-?(NSString?*)description;????@end?? 這里自定義了一個Person類型,實現了NSCoding協議,然后他有三個屬性,這里我們看到有新的方法去定義屬性,這個后面說到內存管理的時候在詳細說明。
?
?
Person.m
?
[objc]?view plaincopy
??#import?"Person.h"????@implementation?Person????-?(id)initWithCoder:(NSCoder?*)aDecoder{??????NSLog(@"initWithCoder");??????self?=?[super?init];??????if(self?!=?nil){??????????????????????????_name?=?[[aDecoder?decodeObjectForKey:@"name"]?copy];??????????self.age?=?[aDecoder?decodeObjectForKey:@"age"];??????????self.apples?=?[aDecoder?decodeObjectForKey:@"apples"];????????????????}??????return?self;??}????-?(void)encodeWithCoder:(NSCoder?*)aCoder{??????NSLog(@"encodeWithCoder");??????[aCoder?encodeObject:_name?forKey:@"name"];????[aCoder?encodeInteger:_age?forKey:@"age"];??????[aCoder?encodeObject:_apples?forKey:@"apples"];??}????-?(NSString?*)description{??????NSString?*string?=?[NSString?stringWithFormat:@"name=%@,age=%d,apples=%@",_name,_age,_apples];??????return?string;??}????@end?? 在Person.m文件中,我們需要實現協議中的兩個方法:
?
?
initWithCoder
encodeWithCoder
這兩個方法一個是用于歸檔操作時會調用的方法,還有一個是用于解檔操作時會調用的方法
1、解檔的時候用到的方法
?
[objc]?view plaincopy
-?(id)initWithCoder:(NSCoder?*)aDecoder{??????NSLog(@"initWithCoder");??????self?=?[super?init];??????if(self?!=?nil){??????????????????????????_name?=?[[aDecoder?decodeObjectForKey:@"name"]?copy];??????????self.age?=?[aDecoder?decodeObjectForKey:@"age"];??????????self.apples?=?[aDecoder?decodeObjectForKey:@"apples"];????????????????}??????return?self;??}?? 這個是一個初始化的方法,同時他也是一個解檔操作時會調用的方法,所以在這里我們既要寫一下初始化方法的特定代碼,還要寫上解檔的代碼,這里主要看解檔的代碼
?
其實很簡單,就是對屬性重新寫一下值,然后對每個屬性指定一個key就可以了。這個有點類似于Android中的Parcel
(這里我們看到,在解檔name屬性的時候,用到了copy的一個方法,這個在后面會說到,有淺拷貝和深拷貝之分)
?
2、歸檔的時候用到的方法
?
[objc]?view plaincopy
-?(void)encodeWithCoder:(NSCoder?*)aCoder{??????NSLog(@"encodeWithCoder");??????[aCoder?encodeObject:_name?forKey:@"name"];????[aCoder?encodeInteger:_age?forKey:@"age"];??????[aCoder?encodeObject:_apples?forKey:@"apples"];??}?? 歸檔和解檔的操作正好相反的,但是要注意的是:他們屬性的key一定要保持一致
?
?
3、重寫description方法
[objc]?view plaincopy
-?(NSString?*)description{??????NSString?*string?=?[NSString?stringWithFormat:@"name=%@,age=%d,apples=%@",_name,_age,_apples];??????return?string;??}?? 在之前的文章中我說道過,我們在使用NSLog方法打印對象的值的時候,其實是調用對象的description方法,而這個方法是NSObject類中的,我們可以重寫他,這樣我們就可以打印我們想要的信息了。和Java中的toString方法一樣。
?
?
下面就來看一下使用方法了
main.m
?
[objc]?view plaincopy
??#import?<Foundation/Foundation.h>????#import?"Person.h"??int?main(int?argc,?const?charchar?*?argv[])?{??????@autoreleasepool?{????????????????????Person?*p?=?[[Person?alloc]?init];??????????p.name?=?@"張三";??????????p.age?=?20;??????????p.apples?=?@[@"iphone",@"ipad"];????????????????????????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"person.archiver"];??????????BOOL?success?=?[NSKeyedArchiver?archiveRootObject:p?toFile:filePath];??????????if(success){??????????????NSLog(@"歸檔成功");??????????}????????????????????????????Person?*person?=?[NSKeyedUnarchiver?unarchiveObjectWithFile:filePath];??????????NSLog(@"%@",person);??????????????????????????}??????return?0;??}?? 我們可以看到,使用起來是很簡單的和上面的方式一樣,運行結果:
?
看到了,我們自定義的description方法,打印了我們自己想要的結果~~
?
總結
這一篇文章我們就說了OC中的歸檔和解檔的相關概念和操作,其實說白了就是將對象寫入到文件,和從文件中讀取對象。
轉載于:https://www.cnblogs.com/dreamDeveloper/p/6024929.html
總結
以上是生活随笔為你收集整理的OC学习篇之---归档和解挡的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。