IOS 14.5版本之解档和归档的API学习
IOS 14.5版本之解檔和歸檔的API學習
第一部分 回顧一下老api的使用,將對象持久化至硬盤里面。
1.為什么我們要學習解檔和歸檔,
有什么作用。當 plist 文件存儲無法滿足我們的需求的時候,或者 用戶偏好設置無法存儲我們自定義的對象的時候,就需要解檔和歸檔的知識上場了。首先我們體驗一下IOS12之前API的 解檔和歸檔的知識。IOS12之后,蘋果替換了之前的寫法了。
我們需要重寫學習。不要念想之前的api函數,沒有意義。蘋果既然要廢棄之前的寫法,肯定有它的道理,無需深究。時代在進步,科技在進步。
解檔和歸檔 是針對一個對象進行存儲的。直接把對象存儲在一個abc.arc,或者abc.data里面,放在哪,放在沙盒路徑的documents目錄下,沙盒的根目錄是NSHomeDirection(). 打印的,返回值類型是字符串,關于返回值類型不知道的,可以按住option 鼠標點擊那個類,就看到了。 不知道一些控件的具體方法,可以跳到頭文件,看看源代碼的實現方法,就可以了,ctrl + command + J 是跳入頭文件的利器,必須滾瓜爛熟。
對象的歸檔和解檔,和Java 的加密有點像,有encode方法和decode 方法,學會類比學習。
首先定義一個Person類,寫三個屬性。,并實現NSCoding協議
實現NSCoding協議內的兩個方法。協議方法記不得,可以跳到頭文件看一看。一個解檔用的,一個歸檔用的,說簡單點,一個是存數據的,一個是讀取數據的。
#import "HMPerson.h" @implementation HMPerson /**當將一個自定義的對象保存到文件的中必須實現NSCoding協議*/ ///在該方法中說明如何存儲自定義對象的對象 //也就是說該方法中說清楚存儲自定義對象的哪些屬性 - (void)encodeWithCoder:(NSCoder *)coder{//歸檔用的,重寫父類的方法,從NSCoding 協議獲取[coder encodeObject:self.name1 forKey:@"name1"];[coder encodeInt:self.age forKey:@"age"];[coder encodeDouble:self.hei forKey:@"hei"]; } - (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {//解檔用的,解擋會重寫 NSCoding協議 里面未實現的方法if(self = [super init]){self.name1 = [coder decodeObjectForKey:@"name1"];self.age = [coder decodeIntForKey:@"age"];self.hei = [coder decodeFloatForKey:@"hei"];}return self; } @endstoryboard拖兩個按鈕,一個讀,一個寫,連線至viewController.m 里面,并選取action動作,自己隨便起個名字,略過…
#import "ViewController.h" @interface ViewController () @property(nonatomic,copy)NSString * path; @end @implementation ViewController - (NSString *)path{if(!_path){NSString *doc =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];_path = [doc stringByAppendingPathComponent:@"person.arc"];}return _path; } - (IBAction)read:(id)sender {//直接解擋HMPerson *p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:self.path];NSLog(@"%@,%d,%lf",p2.name1,p2.age,p2.hei); } - (IBAction)saveObject:(id)sender {//1.創建對象HMPerson *p1 = [HMPerson new];p1.name1 = @"daJun";p1.age = 22;p1.hei = 183;NSLog(@"%@",self.path);//2.把對象進行歸檔[NSKeyedArchiver archiveRootObject:p1 toFile:self.path]; } @end 2021-06-10 11:12:42.042287+0800 01-歸檔知識[7791:611590] daJun,22,183.000000Finder 下,command + shift + G ,是前往文件夾,這個快捷鍵必須記住。
finder下,ctrl + command + . 是取消隱藏文件 或者 隱藏文件的。必須知道。
最后看到控制臺打印讀取到的內容,證明原先api可以使用,只是編譯器報了大大的警告,說這個函數在ios12被提出反對,使用xxx進行了替換。咱們就使用它提示的函數進行第二輪測試。
第二部分,新API的使用,將對象持久化至硬盤里面。
定義一個Person類,里面實現兩個協議,<NSCoding,NSSecureCoding>
實現協議內的三個方法。不要問為什么。就是這樣干的
搞個成員變量屬性,給他一下設置懶加載,初始化一下為沙盒目錄的documents目錄里面。
@property(nonatomic,copy)NSString * finalPath; //懶加載 - (NSString *)finalPath{if(!_finalPath){NSString *doc =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];_finalPath = [doc stringByAppendingPathComponent:@"abcd.arc"];NSLog(@"%@",NSHomeDirectory());}return _finalPath; }歸檔action按鈕代碼
- (IBAction)guidang:(id)sender {HMPerson *p1 = [HMPerson new];p1.name1 = @"jack";p1.age = 18;p1.hei = 1.83;NSError *error;NSData *da = [NSKeyedArchiver archivedDataWithRootObject:p1 requiringSecureCoding:YES error:&error];if(da==nil || error){NSLog(@"%@",error);}[da writeToFile:self.finalPath atomically:YES]; }解檔Action按鈕代碼如下
- (IBAction)jiedang:(id)sender {HMPerson * p2= [NSKeyedUnarchiver unarchivedObjectOfClass:[HMPerson class] fromData:[NSData dataWithContentsOfFile:self.finalPath] error:nil];NSLog(@"%@,%d,%lf",p2.name1,p2.age,p2.hei);NSLog(@"%@",@"這是解檔后的內容打印"); }注意,先歸再解,有先后之分的順序之分的。這是IOS12以后的解檔歸檔基礎知識,資源文件為: ios12解檔和歸檔.zip,在我的主頁下面。整個編寫過程,能不用鼠標,盡量不要使用鼠標,全部用快捷鍵,操作各個編輯頁面。使用鼠標很慢,mac的主要思想是全程使用鍵盤。
第三部分,解檔歸檔,帶數組的存儲,即數組類型 的存儲和讀取。
@interface HMPerson : NSObject<NSCoding,NSSecureCoding> @property(nonatomic,copy)NSString * name; @end #import "HMPerson.h" @implementation HMPerson - (void)encodeWithCoder:(NSCoder *)coder{[coder encodeObject:self.name forKey:@"name"]; } - (instancetype)initWithCoder:(NSCoder *)coder{if(self=[super init]){self.name = [coder decodeObjectForKey:@"name"];}return self; } + (BOOL)supportsSecureCoding{return YES; } - (NSString *)description {return [NSString stringWithFormat:@"<%@,%p>{name: %@}", [self class],self,self.name]; } @end數組的讀取與寫入方法的實現,就解檔和歸檔的具體實現,測試,由于重新父類的descration 方法,打印arr才看得清楚。
- (IBAction)w:(id)sender {HMPerson *p = [HMPerson new];p.name = @"Jack";HMPerson *p2 = [HMPerson new];p2.name = @"LuJun";HMPerson *p3 = [HMPerson new];p3.name = @"rose";NSArray *arr = @[p,p2,p3];NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr requiringSecureCoding:YES error:nil];NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString * path =[doc stringByAppendingPathComponent:@"dc.data"];[data writeToFile:path atomically:YES];NSLog(@"%@",NSHomeDirectory());} - (IBAction)r:(id)sender {NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString * path =[doc stringByAppendingPathComponent:@"dc.data"];NSSet *set = [NSSet setWithObjects:[NSArray class],[HMPerson class], nil];NSData *data = [NSData dataWithContentsOfFile:path];NSArray *arr2 = [NSKeyedUnarchiver unarchivedObjectOfClasses:set fromData:data error:nil];NSLog(@"%@",arr2);for(HMPerson *item in arr2){NSLog(@"%@",item.name);} }第四部分 帶繼承的類的歸檔和解檔
#import "HMStudent.h" @implementation HMStudent - (void)encodeWithCoder:(NSCoder *)coder{[super encodeWithCoder:coder];[coder encodeDouble:self.weight forKey:@"weight"]; } - (instancetype)initWithCoder:(NSCoder *)coder{if(self = [super initWithCoder:coder]){self.weight = [coder decodeDoubleForKey:@"weight"];}return self; } + (BOOL)supportsSecureCoding{return YES; } @end - (IBAction)gui2:(id)sender {HMStudent *stu = [HMStudent new];stu.name1 = @"Lili";stu.age = 22;stu.weight = 58.8;NSError *err;NSData *data = [NSKeyedArchiver archivedDataWithRootObject:stu requiringSecureCoding:YES error:&err];if(data==nil || err){NSLog(@"%@",err.description);}[data writeToFile:self.pathss atomically:YES]; }- (IBAction)jie:(id)sender {NSData *data=[NSData dataWithContentsOfFile:self.pathss];HMStudent *str=[NSKeyedUnarchiver unarchivedObjectOfClass:[HMStudent class] fromData:data error:nil];NSLog(@"%@,%d,%lf",str.name1,str.age,str.weight); } @end有個學生類繼承了父類Person類,要用super調用父類的歸檔,initWithCoder 也要調用父類的。否則有問題。
不重寫父類的三個方法,創建子類對象,默認調用父類的方法,導致子類自己的屬性無法得到歸檔,。重寫了父類的三個方法,不調用父類超類方法,僅僅保存子類的屬性內容,子類一旦重新父類方法,實例化子類對象,將不會調用父類方法了。這點要知道。
總結
以上是生活随笔為你收集整理的IOS 14.5版本之解档和归档的API学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 值得借鉴的30条好习惯
- 下一篇: 新手开车 驾驶小秘诀要牢记