Fork me on https://github.com

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.
}

 

posted @ 2015-11-12 21:06  OrangesChen  阅读(666)  评论(0编辑  收藏  举报