日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OC学习篇之---归档和解挡

發布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OC学习篇之---归档和解挡 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天我們來看一下OC中的一個重要知識點:歸檔

OC中的歸檔就是將對象寫入到一個文件中,Java中的ObjectInputStream和ObjectOutputStream來進行操作的。當然在操作的這些對象都是需要實現一個接口:Serializable,同樣的OC中操作的對象也是需要實現一個協議的,后面會說到。

?

一、已有類型的歸檔和解檔

首先來看一個簡單的例子:

?

[objc]?view plaincopy
  • //??
  • //??main.m??
  • //??33_ObjectToFile??
  • //??
  • //??Created?by?jiangwei?on?14-10-13.??
  • //??Copyright?(c)?2014年?jiangwei.?All?rights?reserved.??
  • //??
  • ??
  • #import?<Foundation/Foundation.h>??
  • ??
  • //歸檔:將一個對象寫到文件中??
  • int?main(int?argc,?const?charchar?*?argv[])?{??
  • ????@autoreleasepool?{??
  • ???????//第一種形式:歸檔對象??
  • ???????//對象----》文件??
  • ????????/*?
  • ????????NSArray?*array?=?[NSArray?arrayWithObjects:@"zhang",@"wangwu",@"lisi",nil];?
  • ????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];?
  • ?????????
  • ????????BOOL?success?=?[NSKeyedArchiver?archiveRootObject:array?toFile:filePath];?
  • ????????if(success){?
  • ????????????NSLog(@"保存成功");?
  • ????????}?
  • ?????????*/??
  • ????????/*解歸檔?
  • ????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];?
  • ????????id?array?=?[NSKeyedUnarchiver?unarchiveObjectWithFile:filePath];?
  • ????????NSLog(@"%@",array);?
  • ?????????*/??
  • ??????????
  • ????????//第二種方式??
  • ????????//第一種方式的缺陷是一個對象歸檔成一個文件??
  • ????????//但是第二種方式,多個對象可以歸檔成一個文件??
  • ????????/*?
  • ????????NSArray?*array?=?[NSArray?arrayWithObjects:@"zhangsan",@"lisi",?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"];?
  • ?????????
  • ????????//完成編碼,將上面的歸檔數據填充到data中,此時data中已經存儲了歸檔對象的數據?
  • ????????[archiver?finishEncoding];?
  • ????????[archiver?release];?
  • ?????????
  • ????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];?
  • ????????BOOL?success?=?[data?writeToFile:filePath?atomically:YES];?
  • ????????if(success){?
  • ????????????NSLog(@"歸檔成功");?
  • ????????}?
  • ?????????*/??
  • ??????????
  • ????????NSString?*filePath?=?[NSHomeDirectory()?stringByAppendingPathComponent:@"array.src"];??
  • ????????//讀取歸檔數據??
  • ????????NSData?*data?=?[[NSData?alloc]?initWithContentsOfFile:filePath];??
  • ??????????
  • ????????//創建解歸檔對象,對data中的數據進行解歸檔??
  • ????????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"];??
  • ???
  • ?//完成編碼,將上面的歸檔數據填充到data中,此時data中已經存儲了歸檔對象的數據??
  • ?[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];??
  • ??
  • //創建解歸檔對象,對data中的數據進行解歸檔??
  • 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
  • //??
  • //??Person.h??
  • //??34_ArchiveProtocol??
  • //??
  • //??Created?by?jiangwei?on?14-10-13.??
  • //??Copyright?(c)?2014年?jiangwei.?All?rights?reserved.??
  • //??
  • ??
  • #import?<Foundation/Foundation.h>??
  • ??
  • //類只有實現NSCoding協議才能歸檔??
  • @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
  • //??
  • //??Person.m??
  • //??34_ArchiveProtocol??
  • //??
  • //??Created?by?jiangwei?on?14-10-13.??
  • //??Copyright?(c)?2014年?jiangwei.?All?rights?reserved.??
  • //??
  • ??
  • #import?"Person.h"??
  • ??
  • @implementation?Person??
  • ??
  • //解歸檔的時候調用??
  • //也是一個初始化方法??
  • -?(id)initWithCoder:(NSCoder?*)aDecoder{??
  • ????NSLog(@"initWithCoder");??
  • ????self?=?[super?init];??
  • ????if(self?!=?nil){??
  • ????????/*?
  • ????????_name?=?[aDecoder?decodeObjectForKey:@"name"];?
  • ????????_age?=?[aDecoder?decodeObjectForKey:@"age"];?
  • ????????_apples?=?[aDecoder?decodeObjectForKey:@"apples"];?
  • ?????????*/??
  • ????????//一般我們將key定義成宏,這樣就不會出錯??
  • ????????_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"];//一般key和屬性名是取一樣的??
  • ????[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"];?
  • ????????_age?=?[aDecoder?decodeObjectForKey:@"age"];?
  • ????????_apples?=?[aDecoder?decodeObjectForKey:@"apples"];?
  • ?????????*/??
  • ????????//一般我們將key定義成宏,這樣就不會出錯??
  • ????????_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"];//一般key和屬性名是取一樣的??
  • ????[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
  • //??
  • //??main.m??
  • //??34_ArchiveProtocol??
  • //??
  • //??Created?by?jiangwei?on?14-10-13.??
  • //??Copyright?(c)?2014年?jiangwei.?All?rights?reserved.??
  • //??
  • ??
  • #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学习篇之---归档和解挡的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。