zoukankan      html  css  js  c++  java
  • DataPersistence(数据持久化: 文件读写, NSUserDefault, 归档)

     DataPersistence(数据持久化)

    1.数据持久化?

      数据永久的保存

    2.为什么要做数据持久化?

      要把之前的操作(存档, 记录等)保存起来

    3.为什么数据之前保存不了呢?

      以前的数据都存在内存中, 程序一旦终止, 内存就会被收回

    4.数据保存到哪里, 才能做数据持久化

      把数据存到硬盘里

    5.存到硬盘的哪个位置呢?

      沙盒机制: iOS会为每一个应用, 单独创建一个文件夹(沙盒), 这个文件夹只允许当前应用访问

    6.如何通过代码获取路径?

    7.沙盒文件夹又分了多个子文件夹, 为什么?

      Finder cmd+shift+g 前往文件夹

      子文件夹方便对文件进行管理, 每个文件夹都有不同的作用

    8.如何进行数据持久化?

      数据持久化的方式:

      a.文件读写, 支持数组, 字典, 字符串, NSData, 支持这4种类型的嵌套

      b.NSUserDefault, 单例, 支持基本数据类型 + 对象 + URL

      c.归档, 支持所有类型, 前提, 遵守<NSCoding>协议, 实质: 把数据转成NSData类型, 再把NSData的数据写入文件

      d.数据库

      e.CoreData

    9.完整的数据持久化过程

      a.启动程序后, 从沙盒文件夹中读取文件内容

      b.将内容在合适的控件上展示

      c.如果对内容修改, 应该吧内容存到文件中

      a.文件读写支持数组字典字符串, NSData, 支持这4种类型的嵌套

    #import "ViewController.h"
    @interface ViewController ()<UITextFieldDelegate>
    @property (retain, nonatomic) IBOutlet UITextField *userName;
    @end
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad]; 
        沙盒路径
        NSLog(@"%@", NSHomeDirectory());
        
    //    [NSString stringWithFormat:@"%@/Documents", NSHomeDirectory()];   
        Documents, 文档文件夹, 存放重要的文件(用户配置信息, 存档等), 并且手机连电脑进行同步时, 会同步此文件夹; 文件夹中存的文件体积不能过大
        参数1: 搜索的文件夹名字
        参数2: 搜索区域
        参数3: 相对路径(NO)还是绝对路径(YES)
        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO) firstObject];
        NSLog(@"%@", documentsPath);
        
        Library, 资源文件夹, 存放资源文件(图片, 音频, 视频等)
        NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
        NSLog(@"%@", libraryPath);
        
        tmp, 临时文件夹, 存过渡文件(压缩包)
        NSLog(@"%@", NSTemporaryDirectory());
        
        *.app, 应用包(文件夹), 存放编译过后的文件(可执行文件, nib)和工程资源, 这个文件夹是只读的
        NSLog(@"%@", [[NSBundle mainBundle] bundlePath]);
        [self method2];
        
        [self method3];
        [self method4];
        
        [self method5];
        [self method6];
    }
    
    NSString写入
    - (void)method1 {
       文件读写, 支持: NSString, NSArray, NSDictionary
        如果文件不存在, 就创建文件, 并把内容写入文件
        如果文件存在, 覆盖文件内容
        
        //NSString的写入
        NSString *userName = self.userName.text;
        //参数1: 文件路径
        //参数2: 是否使用辅助文件
        //参数3: 文字编码格式
        //参数4: 是否有错误 error
        NSString *string  = [NSString stringWithFormat:@"%@/aaa.text", NSHomeDirectory()];
        NSError *error = nil;
        BOOL result = [userName writeToFile:string atomically:YES encoding:NSUTF8StringEncoding error:&error];
        if (result) {
            NSLog(@"写入成功");
        } else {
            NSLog(@"写入失败: %@", error);
        }
    }
    
    NSString读取
    - (void)method2 {
        NSError *error = nil;
        NSString *string = [[[NSString alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/aaa.text", NSHomeDirectory()] encoding:NSUTF8StringEncoding error:&error] autorelease];
        if (error) {
            NSLog(@"读取失败:%@", error);
        } else {
            self.userName.text = string;
        }
    }
    
    NSArray的写入
    - (void)method3 {
        NSArray *array = @[@"袜子", @"越南新娘", @"衣服", @"万能胶"];
        NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        字符串路径, 保证两个字符串之间有一个"/"
        NSString *filePath = [documentPath stringByAppendingPathComponent:@"array.plist"];
        //字符串后缀拼接, 保证两个字符串之间有一个"."
    //    NSString *filePath = [documentPath stringByAppendingPathExtension:@"txt"];
        NSLog(@"%@", filePath);
        注: 写入和读取操作, 必须使用绝对路径
        BOOL result = [array writeToFile:[NSString stringWithFormat:filePath, documentPath] atomically:YES];
        if (result) {
            NSLog(@"写入成功!");
        } else {
            NSLog(@"写入失败!");
        }
    }
    
    NSArray读取操作
    - (void)method4 {
        NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        NSArray *array = [[NSArray alloc] initWithContentsOfFile:[documentPath stringByAppendingPathComponent:@"array.plist"]];
        NSLog(@"%@", array);
        [array release];
    }
    
    NSDictionary写入
    - (void)method5 {
        NSDictionary *dic = @{@"name": @"张三", @"gender": @""};
        NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
        NSString *string = [libraryPath stringByAppendingPathComponent:@"dic.plist"];
        NSLog(@"%@", string);
        BOOL result = [dic writeToFile:string atomically:YES];
        if (result) {
            NSLog(@"写入成功");
        } else {
            NSLog(@"写入失败");
        }
    }
    
    NSDictionary读取
    - (void)method6 {
        NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
        NSString *string = [libraryPath stringByAppendingPathComponent:@"dic.plist"];
        NSDictionary *dic = [[NSDictionary alloc] initWithContentsOfFile:string];
        NSLog(@"%@", dic);
        [dic release];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void)dealloc {
        [_userName release];
        [super dealloc];
    }
    
    #pragma mark - UITextFieldDelegate
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        [self method1];
        //键盘回收
        [textField resignFirstResponder];
        return YES;
    }
    @end

    b.NSUserDefault, 单例支持基本数据类型 + 对象 + URL

    #import "OneViewController.h"
    @interface OneViewController ()
    @end
    @implementation OneViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        [self method1];
        [self method2];
    }
    
    NSUserDefualts的写入
    - (void)method1 {
        NSUserDefaults, 支持数据持久化的单例类, NSUserDefualts对应一个文件
        NSLog(@"%@", NSHomeDirectory());
        NSUserDefaults *userDefualts = [NSUserDefaults standardUserDefaults];
        //存数据
        [userDefualts setObject:@"哈哈" forKey:@"string"];
        [userDefualts setBool:YES forKey:@"bool"];
        [userDefualts setFloat:3.14 forKey:@"float"];
        [userDefualts setURL:[NSURL URLWithString:@"www.baidu.com"] forKey:@"url"];
        把内容同步到文件中
        [userDefualts synchronize];
    }
    
    NSUserDefualts的读取
    - (void)method2 {
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        NSString *string = [userDefaults objectForKey:@"string"];
        NSLog(@"%@", string);
        BOOL result = [userDefaults boolForKey:@"bool"];
        NSLog(@"%d", result);
        float number = [userDefaults floatForKey:@"float"];
        NSLog(@"%.2f", number);
        NSURL *url = [userDefaults URLForKey:@"url"];
        NSLog(@"%@", url);
    }

     c.归档支持所有类型前提遵守<NSCoding>协议实质把数据转成NSData类型再把NSData的数据写入文件

    Person.m
    #import "Person.h"
    @implementation Person
    - (void)dealloc
    {
        [_name release];
        [_gender release];
        [_age release];
        [super dealloc];
    }
    
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"name: %@ gender: %@ age: %@", _name, _gender, _age];
    }
    
    #pragma mark - NSCoding
    对这个类的属性进行编码(归档)
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeObject:self.gender forKey:@"gender"];
        [aCoder encodeObject:self.age forKey:@"age"];
        
    }
    对这个类的属性进行解码(反归档)
    - (id)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super init]) {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.gender = [aDecoder decodeObjectForKey:@"gender"];
            self.age = [aDecoder decodeObjectForKey:@"age"];
        }
        return self;
    }
    @end
    #import "TwoViewController.h"
    #import "Person.h"
    @interface TwoViewController ()
    @end
    
    @implementation TwoViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        [self method1];
        [self method2];
    }
    
    归档
    前提: 能够归档的类, 必须遵守<NSCoding>协议
    - (void)method1 {
        //数据
        Person *person = [[Person alloc] init];
        person.name = @"小萝莉";
        person.gender = @"";
        person.age = @"18";
        可变二进制数据, 用于存person数据
        NSMutableData *data = [[NSMutableData alloc] initWithCapacity:0];
        压缩工具
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        把person压入data中
        [archiver encodeObject:person forKey:@"girl"];
        结束编码
        [archiver finishEncoding];
        把data写入文件
        NSString *home = NSHomeDirectory();
        NSString *filePath = [home stringByAppendingPathComponent:@"data.txt"];
        BOOL result = [data writeToFile:filePath atomically:YES];
        if (result) {
            NSLog(@"写入成功");
        } else {
            NSLog(@"写入失败");
        }
        [person release];
        [archiver release];
        [data release];
    }
    
    反归档
    - (void)method2 {
        NSString *home = NSHomeDirectory();
        NSString *filePath = [home stringByAppendingPathComponent:@"data.txt"];
        //去文件中读取data
        NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
        //解压工具
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        Person *person = [unarchiver decodeObjectForKey:@"girl"];
        //完成解压
        [unarchiver finishDecoding];
        NSLog(@"%@", person);
        [unarchiver release];
        [data release];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
  • 相关阅读:
    r_action
    微内核 客户服务器模式 分布式
    机制与策略分离
    自顶向下设计
    swap
    专人写接口+模型,专人写业务逻辑---interface_model -- business logical
    14days laravel
    t
    不用print调试 xdebug ubuntu phpstorm 远程断点调试
    peewee sqlalchemy
  • 原文地址:https://www.cnblogs.com/OrangesChen/p/4960299.html
Copyright © 2011-2022 走看看