zoukankan      html  css  js  c++  java
  • 数据存储之Archiver、Unarchiver、偏好设置

    • 数组的归档
    • 对象的归档
    • NSData多个对象的归档
    • NSArray多个对象的归档
    • 偏好设置的存储

    1.NSString、NSDictionary、NSArray、NSData、NSNumber等类型的对象,可以直接用NSKeyedArchiver进行归档和恢复

    2.不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以

    1⃣️归档和恢复

    支持复杂的数据对象,包括自定义对象。

    对自定义对象进行归档处理,需要实现NSCoding协议

    2⃣️NSCoding协议方法

    encodeWithCoder

    initWithCoder

    3⃣️NSKeyedArchiver & NSKeyedUnarchiver

    4⃣️对于多个对象可以通过NSArray或者NSData进行归档

    一、数组的归档

    // 演练1 NSArray归档
    // 注意,可以通过修改文件名查看归档文件内容
    NSString *path = [docDir stringByAppendingPathComponent:@"array.archive"];
    // 定义数组
    NSArray *array = @[@"张三", @"李四", @"王五"];
    // 归档数组
    [NSKeyedArchiver archiveRootObject:array toFile:path];
    
    // 恢复数组
    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"%@", unarchivedArray);

    二、对象的归档

    1⃣️重写NSCoding两个方法

    // 归档
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:_name forKey:@"name"];
        // 图像数据
        NSData *imageData = UIImagePNGRepresentation(_userImage);
        [aCoder encodeObject:imageData forKey:@"imageData"];
        [aCoder encodeInt:_age forKey:@"age"];
        [aCoder encodeObject:_phone forKey:@"phone"];
    }
    
    // 恢复
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        [self setName:[aDecoder decodeObjectForKey:@"name"]];
        // 图像数据
        NSData *imageData = [aDecoder decodeObjectForKey:@"imageData"];
        [self setUserImage:[UIImage imageWithData:imageData]];
        [self setAge:[aDecoder decodeIntForKey:@"age"]];
        [self setPhone:[aDecoder decodeObjectForKey:@"phone"]];
        
        return self;
    }

    2⃣️归档和恢复

    // 归档文件路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];
    
    // 新建Person对象
    Person *person = [Person initPersonWithName:_userNameText.text image:_userImageView.image age:_ageText.text.intValue phone:_phoneText.text];
    
    // 归档用户数据
    [NSKeyedArchiver archiveRootObject:person toFile:path];
    // 恢复文件路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [documents[0]stringByAppendingPathComponent:@"personInfo.plist"];
    
    // 恢复Person对象
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    
    [_userNameText setText:person.name];
    [_userImageView setImage:person.userImage];
    [_ageText setText:[NSString stringWithFormat:@"%d", person.age]];
    [_phoneText setText:person.phone];

    三、NSData多个对象的归档(用于不同对象)

    1⃣️归档

    // 演练3. 归档多个对象
    - (void)archivedMultiObjects
    {
        // 获取文档目录
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        // 存档路径
        NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers.plist"];
    
        Person *person1 = [Person initPersonWithName:@"张三" image:[UIImage imageNamed:@"头像1.png"] age:18 phone:@"110"];
        Person *person2 = [Person initPersonWithName:@"李四" image:[UIImage imageNamed:@"头像2.png"] age:32 phone:@"120"];
    
        // 新建一块可变的数据区
        NSMutableData *data = [NSMutableData data];
        // 将数据区连接到一个NSKeyedArchiver对象
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
        // 开始存档对象,存档的数据都会存储到NSMutableData中
        [archiver encodeObject:person1 forKey:@"person1"];
        [archiver encodeObject:person2 forKey:@"person2"];
        // 存档完毕(一定要调用这个方法)
        [archiver finishEncoding];
        // 将存档的数据写入文件
        [data writeToFile:path atomically:YES];
    }

    2⃣️恢复

    - (void)unarchiverPersonInfo:(UIButton *)sender
    {
        // 演练3. 恢复NSData归档的多个数据
        // 获取文档目录
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        // 存档路径
        NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers.plist"];
        
        // 演练4. 使用NSArray归档多个对象
        NSString *path2 = [documents[0]stringByAppendingPathComponent:@"multiUsers2.plist"];
        NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
        for (Author *author in array) {
            NSLog(@"%@ %d %@ %@", author.name, author.age, author.phone, author.bookName);
        }
    
        // 从文件读取数据
        NSData *data = [NSData dataWithContentsOfFile:path];
        // 根据数据,解析成一个NSKeyedUnarchiver对象
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
        // 恢复对象
        Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
        Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
        // 恢复完毕(一定要调用这个方法)
        [unarchiver finishDecoding];
    
        // 根据按钮Tag设置UI
        if (sender.tag == 0) {
            [_userNameText setText:person1.name];
            [_userImageView setImage:person1.userImage];
            [_ageText setText:[NSString stringWithFormat:@"%d", person1.age]];
            [_phoneText setText:person1.phone];
        } else {
            [_userNameText setText:person2.name];
            [_userImageView setImage:person2.userImage];
            [_ageText setText:[NSString stringWithFormat:@"%d", person2.age]];
            [_phoneText setText:person2.phone];
        }
    }

     四、NSArray多个对象的归档(用于相同对象)

    1⃣️写一个Author类,继承Person

    类中需要重写两个方法

    // 归档
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [super encodeWithCoder:aCoder];
        
        [aCoder encodeObject:_bookName forKey:@"bookName"];
    }
    
    // 恢复
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        self = [super initWithCoder:aDecoder];
        
        if (self) {
            _bookName = [aDecoder decodeObjectForKey:@"bookName"];
        }
        
        return self;
    }

    2⃣️使用NSArray归档

    // 演练4. 使用NSArray归档多个对象
    - (void)archivedMultiObjectsWithArray;
    {
        // 获取文档目录
        NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        // 存档路径
        NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers2.plist"];
    
        Author *author1 = [Author initPersonWithName:@"张大师" image:[UIImage imageNamed:@"头像1.png"] age:30 phone:@"110" bookName:@"C语言基础"];
        Author *author2 = [Author initPersonWithName:@"张大师" image:[UIImage imageNamed:@"头像1.png"] age:30 phone:@"110" bookName:@"C++宝典"];
    
        NSArray *array = @[author1, author2];
    
        // 注意此处不能使用 [array writeToFile:path atomically:YES];
        [NSKeyedArchiver archiveRootObject:array toFile:path];
    }

    3⃣️解档

    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        // 存档路径
        NSString *path = [documents[0]stringByAppendingPathComponent:@"multiUsers.plist"];
        
        // 演练4. 使用NSArray归档多个对象
        NSString *path2 = [documents[0]stringByAppendingPathComponent:@"multiUsers2.plist"];
        NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
        for (Author *author in array) {
            NSLog(@"%@ %d %@ %@", author.name, author.age, author.phone, author.bookName);
        }

    五、偏好设置的存储

    注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘,应用程序就终止了。

    出现以上问题,可以通过调用synchornize方法强制写入:

    [defaults synchronize];

    1⃣️偏好设置保存

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        
        [defaults setObject:@"王二麻子" forKey:@"UserName"];
        [defaults setFloat:18.5 forKey:@"fontSize"];
        [defaults setBool:NO forKey:@"purchased"];
        
        [[NSUserDefaults standardUserDefaults]setObject:@"110" forKey:@"Phone"];
        // 同步命令
        [[NSUserDefaults standardUserDefaults]synchronize];

    2⃣️取出

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *userName = [defaults objectForKey:@"userName"];
    float fontSize = [defaults floatForKey:@"fontSize"];
    BOOL autoLogin = [defaults boolForKey:@"autoLogin"];
  • 相关阅读:
    zookeeper 4 letter 描述与实践
    zookeeper理论
    Zookeeper的功能以及工作原理
    zookeeper
    VMware安装、配置CentOS
    python安装requests (win7 & centos7)
    Centos 6.4 32位 gcc 升级(已验证)
    Centos6.4编译安装Node.js(已验证)
    使用supervisor提高nodejs调试效率 (已验证)
    tar.xz文件如何解压 (已验证)
  • 原文地址:https://www.cnblogs.com/letougaozao/p/3661171.html
Copyright © 2011-2022 走看看