NSCoding NSKeyedArchiver NSKeyedUnarchiver
来源:互联网 发布:帝国cms视频教程 编辑:程序博客网 时间:2024/06/03 22:59
概述
- 归档与恢复完全类似于其他语言中的序列化和反序列化
- 归档(序列化)是把对象转换为可保存、可传输的数据流
- 恢复(反序列化)是从数据流中恢复对象
NSCoding
@protocol NSCoding- (void)encodeWithCoder:(NSCoder *)aCoder;- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER@end
@interface FBAnimal : NSObject <NSCoding>- (instancetype)initWithAge:(int)age andColor:(int)color andWeight:(double)weight;@property (nonatomic) int age;@property (nonatomic) int color;@property (nonatomic) double weight;@end@implementation FBAnimal- (instancetype)initWithAge:(int)age andColor:(int)color andWeight:(double)weight{ self = [super init]; if(self) { self.age = age; self.color = color; self.weight = weight; } return self;}- (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeInt:self.age forKey:@"age"]; [aCoder encodeInt:self.color forKey:@"color"]; [aCoder encodeDouble:self.weight forKey:@"weight"];}- (instancetype)initWithCoder:(NSCoder *)aDecoder;{ self.age = [aDecoder decodeIntForKey:@"age"]; self.color = [aDecoder decodeIntForKey:@"color"]; self.weight = [aDecoder decodeDoubleForKey:@"weight"]; return self;}-(void)info{ NSLog(@"age = %d", self.age); NSLog(@"color = %d", self.color); NSLog(@"weight = %f", self.weight);}@end
NSKeyedArchiver
- (void)encodeObject:(nullable id)objv forKey:(NSString *)key;- (void)encodeConditionalObject:(nullable id)objv forKey:(NSString *)key;- (void)encodeBool:(BOOL)boolv forKey:(NSString *)key;- (void)encodeInt:(int)intv forKey:(NSString *)key;// native int- (void)encodeInt32:(int32_t)intv forKey:(NSString *)key;- (void)encodeInt64:(int64_t)intv forKey:(NSString *)key;- (void)encodeFloat:(float)realv forKey:(NSString *)key;- (void)encodeDouble:(double)realv forKey:(NSString *)key;- (void)encodeBytes:(nullable const uint8_t *)bytesp length:(NSUInteger)lenv forKey:(NSString *)key;
encode各种数据类型,encodeObject本质就是调用object的encodeWithCoder:
NSKeyedUnarchiver
- (nullable id)decodeObjectForKey:(NSString *)key;- (BOOL)decodeBoolForKey:(NSString *)key;- (int)decodeIntForKey:(NSString *)key;// may raise a range exception- (int32_t)decodeInt32ForKey:(NSString *)key;- (int64_t)decodeInt64ForKey:(NSString *)key;- (float)decodeFloatForKey:(NSString *)key;- (double)decodeDoubleForKey:(NSString *)key;- (nullable const uint8_t *)decodeBytesForKey:(NSString *)key returnedLength:(nullable NSUInteger *)lengthp NS_RETURNS_INNER_POINTER;// returned bytes immutable, and they go away with the unarchiver, not the containing autorelease pool
decode各种数据类型,decodeObjectForKey的本质就是调用object的initWithCoder:
归档和恢复单一对象
NSKeyedArchiver
+ (NSData *)archivedDataWithRootObject:(id)rootObject;+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
分析:
- 前者归档(序列化)单一对象到NSData
- 后者归档(序列化)单一对象到文件中
- 上面方法的本质是生成一个NSKeyedArchiver实例对象,然后调用rootObject的encodeWithCoder:,把生成的NSKeyedArchiver实例对象作为参数传入,在encodeWithCoder:中完成归档(序列化)到NSData中,只不过前者直接返回NSData,后者则多了一个步骤把NSData写入本地文件
NSKeyedUnarchiver
+ (nullable id)unarchiveObjectWithData:(NSData *)data;+ (nullable id)unarchiveObjectWithFile:(NSString *)path;
分析:
- 前者恢复(反序列化)NSData到单一对象
- 后者恢复(反序列化)文件到单一对象
- 上面方法的本质是生成一个NSKeyedUnarchiver实例对象(data作为数据传入),再生成一个要恢复的目标对象(data中保存了类型相关信息,根据类型相关信息生成目标实例对象),然后调用目标对象的initWithCoder:,把生成的NSKeyedUnarchiver实例对象作为参数传入,在initWithCoder:中完成恢复(反序列化),最后返回恢复(反序列化)完成的目标实例对象,前者直接使用NSData传入序列化数据,后者则多了一个步骤把文件读入到NSData
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *docDir = [paths objectAtIndex:0];NSString *file = [NSString stringWithFormat:@"%@/%@", docDir, @"animal.archive"]; FBAnimal *animal = [[FBAnimal alloc] initWithAge:5 andColor:8 andWeight:58];[NSKeyedArchiver archiveRootObject:animal toFile:file]; FBAnimal *otherAnimal = [NSKeyedUnarchiver unarchiveObjectWithFile:file]; NSLog(@"animal = %p", animal);[animal info];NSLog(@"otherAnimal = %p", otherAnimal);[otherAnimal info];
output:
animal = 0x7f95a1d4efe0age = 5color = 8weight = 58.000000otherAnimal = 0x7f95a1d52700age = 5color = 8weight = 58.000000
注:animal和otherAnimal指向不同的实例对象,但是内容相同
结论:
- 归档(序列化)对象的本质是调用对象的encodeWithCoder:
- 恢复(反序列化)对象的本质是调用对象的initWithCoder:
- 对象要支持归档(序列化)和恢复(反序列化)必须实现NSCoding protocol
归档和恢复任意多个对象
NSKeyedArchiver
- (instancetype)initForWritingWithMutableData:(NSMutableData *)data;
分析:
- 使用一个NSMutableData类型作为参数传入,然后不断encodeXXX:forKey:要归档(序列化)的数据
NSKeyedUnarchiver
- (instancetype)initForReadingWithData:(NSData *)data;
分析:
- 使用一个NSData(已经序列化的源数据)类型作为参数传入,然后不断调用decodeXXX:forKey:要恢复(反序列化)的数据
NSMutableData *mutableData = [NSMutableData data];NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutableData]; FBAnimal *animal1 = [[FBAnimal alloc] initWithAge:15 andColor:18 andWeight:158];FBAnimal *animal2 = [[FBAnimal alloc] initWithAge:25 andColor:28 andWeight:258];FBAnimal *animal3 = [[FBAnimal alloc] initWithAge:35 andColor:38 andWeight:358];int animalNum = 3;NSLog(@"mutableData length = %lu", mutableData.length);[archiver encodeInt:animalNum forKey:@"animalNum"];[archiver encodeObject:animal1 forKey:@"animal1"];[archiver encodeObject:animal2 forKey:@"animal2"];[archiver encodeObject:animal3 forKey:@"animal3"];NSLog(@"mutableData length = %lu", mutableData.length);[archiver finishEncoding];NSLog(@"mutableData length = %lu", mutableData.length); NSLog(@"animalNum = %d", animalNum);NSLog(@"animal1 = %p, animal2 = %p, animal3 = %p", animal1, animal2, animal3);[animal1 info];[animal2 info];[animal3 info]; NSData *data = [mutableData copy];NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];data = nil;int otherAnimalNum = [unarchiver decodeIntForKey:@"animalNum"];FBAnimal *otherAnimal3 = [unarchiver decodeObjectForKey:@"animal3"];FBAnimal *otherAnimal2 = [unarchiver decodeObjectForKey:@"animal2"];FBAnimal *otherAnimal1 = [unarchiver decodeObjectForKey:@"animal1"]; NSLog(@"otherAnimalNum = %d", otherAnimalNum);NSLog(@"otherAnimal1 = %p, otherAnimal2 = %p, otherAnimal3 = %p", otherAnimal1, otherAnimal2, otherAnimal3);[otherAnimal1 info];[otherAnimal2 info];[otherAnimal3 info];[unarchiver finishDecoding];
output:
mutableData length = 0mutableData length = 0mutableData length = 396animalNum = 3animal1 = 0x7fc7a0f505c0, animal2 = 0x7fc7a0f4ef30, animal3 = 0x7fc7a0f4fc90age = 15color = 18weight = 158.000000age = 25color = 28weight = 258.000000age = 35color = 38weight = 358.000000otherAnimalNum = 3otherAnimal1 = 0x7fc7a0f544f0, otherAnimal2 = 0x7fc7a0f544d0, otherAnimal3 = 0x7fc7a0f54350age = 15color = 18weight = 158.000000age = 25color = 28weight = 258.000000age = 35color = 38weight = 358.000000
分析:
- 归档(序列化)的时候,先把encode的数据放入NSKeyedArchiver实例对象自身的缓存,只有调用finishEncoding后,才会把NSKeyedArchiver的数据缓存copy到NSMutableData
- 恢复(反序列化)的时候,先把NSData的数据缓存copy到NSKeyedUnarchiver实例对象自身的缓存,然后对NSKeyedUnarchiver实例对象自身的缓存decode,finishDecode结束decode
深复制应用
FBAnimal *animal1 = [[FBAnimal alloc] initWithAge:15 andColor:18 andWeight:158];FBAnimal *animal2 = [[FBAnimal alloc] initWithAge:25 andColor:28 andWeight:258];NSDictionary *animalDict = [NSDictionary dictionaryWithObjectsAndKeys:animal1, @"harry", animal2, @"tom", nil];NSData *animalData = [NSKeyedArchiver archivedDataWithRootObject:animalDict];NSDictionary *otherAnimalDict = [NSKeyedUnarchiver unarchiveObjectWithData:animalData]; FBAnimal *otherAnimal1 = [otherAnimalDict objectForKey:@"harry"];FBAnimal *otherAnimal2 = [otherAnimalDict objectForKey:@"tom"]; NSLog(@"animalDict = %p, animal1 = %p, animal2 = %p", animalDict, animal1, animal2);[animal1 info];[animal2 info];NSLog(@"otherAnimalDict = %p, otherAnimal1 = %p, otherAnimal2 = %p", otherAnimalDict, otherAnimal1, otherAnimal2);[otherAnimal1 info];[otherAnimal2 info];
output:
animalDict = 0x7fc1e95c41d0, animal1 = 0x7fc1e95c0160, animal2 = 0x7fc1e95c24c0age = 15color = 18weight = 158.000000age = 25color = 28weight = 258.000000otherAnimalDict = 0x7fc1e95c62d0, otherAnimal1 = 0x7fc1e95c5b80, otherAnimal2 = 0x7fc1e95c5f60age = 15color = 18weight = 158.000000age = 25color = 28weight = 258.000000
1 0
- NSCoding NSKeyedArchiver NSKeyedUnarchiver
- foundation——NSCoding NSKeyedArchiver NSKeyedUnarchiver
- NSCoding / NSKeyedArchiver
- NSCoding/NSKeyedArchiver
- Foundation--NSKeyedArchiver与NSKeyedUnarchiver
- 归档NSCoding、NSKeyedArchiver
- ios:NSKeyedArchiver/NSKeyedUnarchiver(归档/解档)
- iOS 归档(NSKeyedArchiver + NSCoding)
- NSKeyedArchiver、NSKeyedUnarchiver 数据持久化归档
- NSKeyedArchiver/NSKeyedUnarchiver归档解归档的使用
- 使用NSKeyedArchiver归档和NSKeyedUnarchiver读档
- 30 Foundation框架之NSKeyedArchiver和NSKeyedUnarchiver
- IOS持久化之NSKeyedArchiver,NSKeyedUnarchiver
- iOS开发------本地存储-NSKeyedArchiver & NSKeyedUnarchiver(归档)
- ios ---对模型对象归档(NSKeyedArchiver、NSKeyedUnarchiver)
- iOS——NSKeyedArchiver与NSKeyedUnarchiver
- 数据缓存——NSKeyedArchiver归档(NSCoding)
- NSKeyedArchiver/NSCoding归档(序列化)
- DES对称加密算法 CryptoUitls
- html(1)之标签
- ODPS技术架构及应用实践
- 对程序员来说,提高薪水最好的建议是什么?
- 07-掌握-GCD基本使用
- NSCoding NSKeyedArchiver NSKeyedUnarchiver
- AsycTask------MainActivity
- 关于多分类器融合算法
- 手写数字识别(1)---- Softmax回归模型
- Kotlin开发Android笔记2:Kotlin与Java简单比较
- JS 之 appendChild 与 innerHTML
- Debugging performance issues in Go programs
- 二、LVS负载均衡搭建
- codeforces 268E Playlist(数学期望)