歸檔解檔(編碼解碼)


1.理解

a.  如果對象是NSStringNSDictionaryNSArrayNSDataNSNumber等類型可以直接用NSKeyedArchiver進行歸檔和恢復;
b. 不是所有的對象都可以直接用這種方法進行歸檔,只有遵守了NSCoding協議的對象纔可以;

2. NSCoding協議的2個方法:

uencodeWithCoder:

每次歸檔對象時,都會調用這個方法。一般在這個方法裏面指定如何歸檔對象中的每個實例變量,可以使用encodeObject:forKey:方法歸檔實例變量。

uinitWithCoder:

每次從文件中恢復(解碼)對象時,都會調用這個方法。一般在這個方法裏面指定如何解碼文件中的數據爲對象的實例變量,可以使用decodeObject:forKey方法解碼實例變量。


3.系統對象的歸檔解檔(編碼解碼)示例:

a. 歸檔一個NSArray對象到Documents/array.archive;

NSArray*array = [NSArray arrayWithObjects:@”a”,@”b”,nil];

[NSKeyedArchiver archiveRootObject:array toFile:path];


b. 恢復(解碼)NSArray對象;

NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];


4. 自定義對象歸檔/解檔總結:

 1.如果要存儲自定義對象一定要用歸檔/解檔”的操作;

 2.plist.偏好設置都不能用來存儲自定義的對象;

 3.自定義對象歸檔/解檔的時候一定要遵守<NSCoding>的協議;

 4.只要解析文件都會調用initWithCoder:的方法; 

 5.在解檔屬性的時候記得給屬性賦值!!!!

 6.爲什麼要遵守<NSCoding>協議? 爲了告訴系統歸檔/解檔哪些屬性,告訴系統如何進行歸檔解檔。


5.注意:
如果父類也遵守了NSCoding協議,請注意:
a. 應該在encodeWithCoder:方法中加上一句:[super encodeWithCode:encode];確保繼承的實例變量也能被編碼,即也能被歸檔。
b. 應該在initWithCoder:方法中加上一句:self = [super initWithCoder:decoder];確保繼承的實例變量也能被解碼,即也能被恢復。
c.  一般繼承自 NSObject 的類不需要寫super方法,因爲NSObject作爲基類並沒有遵守NSCoding協議,但是在解檔時要寫上self = [super init]。


6. 一個自定義對象的歸檔解檔Demo:


==================創建一個遵守 NSCoding 協議的類=========================

@interface Teacher : NSObject <NSCoding>

@property (nonatomic, assign) int age;

@property (nonatomic, copy) NSString* name;

@end


#import "Teacher.h"

@implementation Teacher

// 告訴系統需要歸檔哪些屬性

- (void)encodeWithCoder:(NSCoder*)aCoder

{

    [aCoder encodeInt:_age forKey:@"age111111"];

    [aCoder encodeObject:_name forKey:@"name"];

}


// 告訴系統解檔哪些屬性

- (id)initWithCoder:(NSCoder*)aDecoder

{

    if (self = [super init]) {

        _age = [aDecoder decodeIntForKey:@"age111111"];

        _name = [aDecoder decodeObjectForKey:@"name"];

    }

    return self;

}

@end


==================創建一個導入了 自定義Teacher類的控制器 ViewController =========================

#import "ViewController.h"

#import "Teacher.h"

@interface ViewController ()

@end


@implementation ViewController


// 存數據

- (IBAction)save:(id)sender

{

    // tmp

    NSString* tmpPath = NSTemporaryDirectory();

    NSString* filePath = [tmpPath stringByAppendingPathComponent:@"teacher.data"];


    Teacher* t = [[Teacher alloc] init];

    t.name = @"傳智播客";

    t.age = 18;


    [NSKeyedArchiver archiveRootObject:t toFile:filePath];    

}


// 取數據

- (IBAction)read:(id)sender

{

    NSString* tmpPath = NSTemporaryDirectory();

    NSString* filePath = [tmpPath stringByAppendingPathComponent:@"teacher.data"];


    Teacher* t = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

    NSLog(@"%d", t.age);

}



發佈了53 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章