zoukankan      html  css  js  c++  java
  • 序列化 NSKeyedArchiver,NSPropertyListSerialization

    到目前为止,看到oc实现的序列化方式有两种:NSKeyedArchiver,NSPropertyListSerialization。

    在这两种序列化方式中,NSData都是序列化的目标。两种方式的不同点在于NSPropertyListSerialization只是针对字典类型的,而NSKeyedArchiver是针对对象的。(补充一下,在Mac OS环境下,还可以使用NSArchiver获得更加精简的二进制序列化内容,但是NSArchiver在iOS环境下不支持)。

    首先讲NSPropertyListSerialization,这个相对简单,只要创建一个NSDictionary,然后调用NSPropertyListSerialization dataFromPropertyList, 将内容写入NSData中就可以了。如果要读入,就调用propertyListFromData.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    NSString * filepath = @”…”;//omitted.
    NSString * err;//不需要初始化。如果有错误发生,会被复制。
    NSDictionary * props = [NSDictionary dictionaryWithObjectsAndKey:@”Lucy”, @"name”,
                @"Beijing, China”, @"city”,
                @"supervior”, @"position”,
                @"Qitiandasheng”, @"company”, nil];
    NSData * data = [NSPropertyListSerialization dataFromPropertyList:props
            format:NSPropertyListXMLFormat_v1_0
            errorDescription:&err];
    if(!err){
        [data writeToFile:filePath atomically:YES];//写入文件
    }else{
        NSLog(@"error with:%@", err);
    }

    然后再来看NSKeyedArchiver。从基本的代码示例来看也很简单:

    1
    2
    3
    4
    5
    Person  * lucy  = [[Person alloc] initWithName:@"lucy"];
    lucy.address = @"Beijing, China";
     
    NSData * data = [NSKeyedArchiver archiveDataWithRootObject:lucy];
    [data writeToFile:filePath];

    这里要求Person类必须事先了NSCoding协议。NSCoding协议中包含两个必须事先的方法initWithCoder和encodeWithCoder. 参考下面这两个方法的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -(void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodingObject:[NSNumber numberWithInt:self.age] forKey @"age"];
    }
    -(id)initWithCoder:(NSCoder*) aDecoder{
        if(self=[super init]){
            self.age = (int)[(NSNumber*)[aDecoder decodeObjectForKey:@"age"] intValue];
        }
        return self;
    }

    这里之所以用int age作为序列化属性的示例,是为了引出另一个话题,就是在序列化时对基础类型的处理。NSCoder中是不能存储基础类型的,包括int,float,char *什么的。要将这些进行序列化,必须要进行封装。

    一般封装有两种方式。对于数值基本类型,使用Cocoa提供的封装,NSNumber就可以了。对于定长的struct,要分情况,如果struct的所有类型都是定长,并且成员中没有struct类型,那么可以直接使用NSValue来封装;否则,需要自己想办法进行key-value编写。char * 应该直接使用NSString进行封装。

  • 相关阅读:
    spring源码解析-ApplicationContext解析
    分布式系统的CAP理论
    Java常用设计模式详解1--单例模式
    mysql全方位知识大盘点
    重磅!微软发布 Visual Studio Online:Web 版 VS Code + 云开发环境
    知否知否,VS Code 不止开源
    webpack静态资源拷贝插件
    webpack 清理旧打包资源插件
    webpack 配置分离css插件
    webpack打包指定HTML的文件并引入指定的chunks
  • 原文地址:https://www.cnblogs.com/worldtraveler/p/4568044.html
Copyright © 2011-2022 走看看