1. 程式人生 > >iOS-NSCoder的用法

iOS-NSCoder的用法

iOS物件序列化與反序列化( NScoder 和 NScoding )

面向物件的程式在執行的時候會建立一個複雜的物件圖,經常要以二進位制的方法序列化這個物件圖,這個過程叫做Archiving. 二進位制流可以通過網路或寫入檔案中(來源於某教材的一段話)

本人的理解是當你於寫資料需要本地儲存時,即將你的資料寫到硬碟上的時候,你就必須對他進行序列化,轉換成二進位制檔案,從而便於在磁碟上的讀寫,同理在取出的時候必須將其在反序列化,這樣才能將資料讀出來,就好比加密和揭祕的過程。

為什麼我將資料寫到plist 中的時候,也是儲存到本地的磁碟上,但是我就沒有序列化啊?

大家有沒有發現,其實plist 的資料是型別是有限制的,就那麼幾種特定的資料型別,nsstring ,大家有沒有嘗試過將一個自己定義的類放進去(寫進plist ),在讀出來?
結果是什麼大家可以先猜想。
其實在nsstring 的類的定義中已經添加了協議 即他是實現了nscoding 代理的方法的。
@interface NSString : NSObject

深入

NScoder 和 NScoding
NScoding 是一個協議,主要有下面兩個方法

//從coder中讀取資料,儲存到相應的變數中,即反序列化資料
-(id)initWithCoder:(NSCoder *)coder;
// 讀取例項變數,並把這些資料寫到coder中去。序列化資料
-(void)encodeWithCoder:(NSCoder *)coder;

NSCoder 是一個抽象類,抽象類不能被例項話,只能提供一些想讓子類繼承的方法。

//從二進位制流讀取物件。
NSKeyedUnarchiver
//把物件寫到二進位制流中去。   
NSKeyedArchiver       

一個簡單的例子

#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    NSString *name;
    char sex;
    int age;
}
@property(nonatomic,copy) NSString *name;
@property char sex;
@property int age;
@end

person.m實現檔案

#import "Person.h"
 

@implementation Person
@synthesize name,age,
gender; -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:name forKey:@"stuName"]; NSNumber *age1 = [NSNumber numberWithInt:age]; [aCoder encodeObject:age1 forKey:@"stuAge"]; NSNumber *gender1 = [NSNumber numberWithChar:gender]; [aCoder encodeObject:gender1 forKey:@"stuGender"]; } -(id)initWithCoder:(NSCoder *)dCoder { name = [dCoder decodeObjectForKey:@"stuName"]; age = [[dCoder decodeObjectForKey:@"stuAge"]intValue]; gender = [[dCoder decodeObjectForKey:@"stuGender"]charValue]; return self; } @end

main.m測試檔案

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p1 = [[Person alloc]init];
        p1.name = @"zhangsan";
        p1.age = 22;
        p1.gender = 'F';
        Person *p2 = [Person new];
        p2.name = @"lisi";
        p2.age = 23;
        p2.gender = 'M';
        
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:30];
        
        [dic setObject:p1 forKey:@"person1"];
        [dic setObject:p2 forKey:@"person2"];
        //把字典內容存入到檔案中
        if ([NSKeyedArchiver archiveRootObject:dic toFile:@"/Users/mac/Desktop/a.plist"] ) {
            NSLog(@"chenggong");
        }
        
        NSMutableDictionary *dic2 = [NSMutableDictionary dictionaryWithCapacity:30];
        //從檔案中讀取內容放入到字典中
        dic2 = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/mac/Desktop/a.plist"];
        NSEnumerator *enumerator = [dic2 objectEnumerator];
        id obj;
        //遍歷字典內容
        while (obj = [enumerator nextObject]) {
            NSLog(@"name = %@,age = %i,gender = %c",[obj name],[obj age],[obj gender]);
        }
    }
    return 0;
}