NSData
對象轉爲NSData 這個過程稱爲序列化,NSData轉對象稱爲反序列化。
任何對象轉NSData,都須要遵循一個協議,就是NSCoding。
NSCoding 是把數據存儲在iOS和Mac OS上的一種極其簡單和方便的方式,把模型對象直接轉變成一個文件,而後再把文件從新加載到內存裏,並不須要任何文件解析和序列化的邏輯。經過擴展你的數據類來支持encode 和 decode 功能就能夠了。
NSCoding 是一個簡單的協議 包含:
-initWithCoder:
-encodeWithCoder:
遵循NSCoding 協議的類能夠被序列化和反序列化。
NSCoder 是一個抽象類,抽象類不能被實例化
NSKeyedUnarchiver 從二進制流讀取對象
NSKeyedArchiver 把對象寫到二進制流中去
舉例:
@interface Student : NSObject<NSCopying,NSCoding>
@property (nonatomic, strong) NSString *studentName;
@property (nonatomic, strong) NSString *score;
@end
@implementation Student
//解碼
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.studentName = [aDecoder decodeObjectForKey:@"studentName"];
self.score = [aDecoder decodeObjectForKey:@"score"];
}
return self;
}
//編碼
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.studentName forKey:@"studentName"];
[aCoder encodeObject:self.score forKey:@"score"];
}
@end
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];
Student *student2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
這樣就創建了任何對象和NSData 之間的橋樑。
利用NSData 進行存儲和深拷貝
實現NSCoding 的類,並序列化數據,有兩個好處
1.序列化數據能夠直接進行存儲
2.序列化數據容易進行徹底拷貝
將某個對象轉NSData ,而後NSData 轉回賦值給新建對象。
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:oldContactsArray];
NSMutableArray *newContactsArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSSecureCoding
使用NSCoding來讀寫用戶數據文件的問題在於,把所有的類編碼到一個文件裏,也就意味着給了這個文件訪問你APP裏面實例類的權限。
NSSecureCoding 除了在解碼時要指定key和要解碼的對象的類,若是要求的類和從文件中解碼出的對象的類不匹配,NSCoder會拋出異常,表明數據已經被篡改了。
符合NSSecureCoding 協議並重寫了-initWithCoder 的類應該使用 -decodeObjectOfClass:forKey:
而不是 -decodeObjectForKey:
舉例
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
// self.studentName = [aDecoder decodeObjectForKey:@"studentName"];
// self.score = [aDecoder decodeObjectForKey:@"score"];
self.studentName = [ aDecoder decodeObjectOfClass:[NSString class] forKey:@"studentName"];
self.score = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"score"];
}
return self;
}
NSCoding 是基礎類庫中將對象歸檔到文件系統上,或者複製到另外一個地址空間的方式。
若是用-decodeObjectForKey: 用於把對象解碼成實際的對象,就不能保證建立的對象是預期的結果。
擴展:
關於使用runtime 自定實現NSCoding