美文网首页
本地存取、本地存储

本地存取、本地存储

作者: PZcoder | 来源:发表于2017-01-20 11:33 被阅读24次

    目录:
    1、常见5种本地存取方法简介
    2、沙盒存储机制浅析
    3、NSUserDefaults
    4、Plist文件读写
    5、第三方FMDB
    6、归档、解档方法介绍

    1、常见5种本地存取方法简介

    1. NSUserDefaults(偏好设置)

    NSUserDefaults是一个单例,在整个程序中只有一个实例对象,他可以用于数据的永久保存,而且简单实用,这是它可以让数据自由传递的一个前提,也是大家喜欢用它保存简单数据的一个主要原因。

    NSUserDefaults适用用户的属性设置等轻量级存储,以键值的形式保存数据

    1. plist文件(完整存取,少量数据)

    plist是property list的缩写。plist中包括一些命名值和使用Core Foundation类型创建的值的列表。这些类型包括CFString, CFNumber, CFBoolean, CFData, CFDate, CFArray, 以及CFDictionary。利用这些类型创建的数据能够高效的组织、存储和访问。plist编程接口使得分级组织的数据类型能够和XML之间相互转换。XML数据可以存储下来以便以后重建原来的一些Core Fundation对象。

    plist应当用于主要是由字符串和数字组成的数据,否则的话它一般效率都会较低。

    3)SQLite(适合存储大量数据、常用第三方FMDB)

    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。

    安卓和ios开发使用的都是SQLite数据库

    1)它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
    2)它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快

    4)归档、解档

    归档可以实现把自定义的对象存放在文件中。
    优点:可以保存自定义对象类型。

    1. CoreData

    Coredata用作数据持久化,使和大数据量的存储和查询。

    Core Date是ios3.0后引入的数据持久化解决方案,它是是苹果官方推荐使用的,不需要借助第三方框架。Core Date实际上是对SQLite的封装,提供了更高级的持久化方式。在对数据库操作时,不需要使用sql语句,也就意味着即使不懂sql语句,也可以操作数据库中的数据。

    在使用CoreData之前,需要导入CoreData框架。

    优点:Core Data实际上是将数据库的创建、表的创建、对象和表的转换等操作封装起来,极大的简化了我们的操作。Core Date与SQLite相比较,SQLite比较原始,操作比较复杂,使用的是C的函数对数据库进行操作,但是SQLite可控性更强,并且能够跨平台。

    CoreData缺点:
    存储性能一般,默认建立的表没有主键,效率低,复杂的查询更是不敢想像。

    2、沙盒存储机制浅析

    沙盒简介:
    iOS程序默认情况下只能访问程序自己的目录,这个目录被称为“沙盒”。

    一.沙盒的结构

    沙盒的目录结构如下:
    1、"应用程序包"
    2、Documents
    3、Library(包含Caches、Preferences两个文件夹)
    4、tmp

    二.沙盒的目录特性

    虽然沙盒中有这么多文件夹,但是每种文件夹都不尽相同,都有各自的特性。
    所以在选择存放目录时,一定要认真选择适合的目录。

    1."应用程序包": 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。

    //通过以下方法可以打印路径
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSLog(@ "%@" , path);
    

    2.Documents: 最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。

    //通过以下方法可以打印路径
    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSLog(@ "%@" , path);
    

    3.Library/Caches: iTunes不会同步此文件夹,
    适合存储体积大,不需要备份的非重要数据。
    Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,
    通常保存应用的设置信息。

    //通过以下方法可以打印路径
    NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    NSLog(@ "%@" , path);
    

    4.tmp: iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。

    //通过以下方法可以打印路径
    NSString *path = NSTemporaryDirectory();
    NSLog(@ "%@" , path);
    

    3、NSUserDefaults

    #pragma mark NSUserDefaults(适用保存用户的属性设置等轻量级存储,以键值的形式保存数据)。
    
    //打印沙盒路径
        NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = arr[0];
        NSLog(@"path = %@",path);
        /*参数说明
         1.NSDocumentDirectory或者NSLibraryDirectory
         2.指定 NSUserDomainMask
         3.是否安全 YES
         */
    
    #pragma mark 写入数据
    - (void)writeData
    {
        //首先获取NSUserDefaults对象
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
        //写入基本数据类型
        [defaults setInteger:100 forKey:@"int"];
        [defaults setDouble:10.9 forKey:@"double"];
        [defaults setBool:YES forKey:@"bool"];
        
        //写入对象类型
        [defaults setObject:@"iOS86" forKey:@"string"];
        [defaults setObject:@[@"aaa",@"bbb"] forKey:@"arr"];
        [defaults setObject:@{@"1":@"a",@"2":@"b"} forKey:@"dic"];
        [defaults setObject:[NSDate date] forKey:@"date"];
    
        //同步数据
        [defaults synchronize];//默认为不定时同步
    //如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。
    //所以如果需要立即写入文件的就必须调用synchronize方法。
    }
    
    #pragma mark 从沙盒目录获取数据
    - (void)getData
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSString *string = [defaults objectForKey:@"string"];
        NSLog(@"string = %@",string);
    
        //获取基本数据类型
        NSInteger a = [defaults integerForKey:@"int"];
        NSLog(@"a == %ld",(long)a);
    }
    

    4、Plist文件读写

    plist文件是将某些特定的类,通过XML文件的方式保存在目录中。

    可以被序列化的类型只有如下几种:

    1.NSArray/2.NSMutableArray;
    3.NSDictionary/4.NSMutableDictionary;
    5.NSData/6.NSMutableData;
    7.NSString/8.NSMutableString;
    9.NSNumber;
    10.NSDate;
    

    1.获得文件路径

    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSString *fileName = [path stringByAppendingPathComponent:@ "123.plist" ];
    

    2.存储

    //执行此行代码时默认新创建一个plist文件
    NSArray *array = @[@ "123" , @ "456" , @ "789" ];
    [array writeToFile:fileName atomically:YES];
    

    3.读取

    //如果存储的是其他类型数据,使用相应类型接收。
    NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
    NSLog(@ "%@" , result);
    

    4.注意:

    只有以上列出的类型才能使用plist文件存储。

    存储时使用writeToFile: atomically:方法。
    其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。
    这是更安全的写入文件方法,一般都写YES。

    读取时使用arrayWithContentsOfFile:方法。

    5、第三方FMDB

    1.首先导入libsqlite3.tbd
    2.导入第三方FMDB
    GitHub下载地址:https://github.com/ccgus/fmdb
    3、如果是MVC开发模式,请单独创建Manager与数据库通信

    ViewController.m代码

    /*
     说明:几个简单的基本的sql语句)
     (查)选择:select * from table1 where
     (增)范围插入:insert into table1(field1,field2) values(value1,value2)
                              表名----字段------------values(字段的值)
     删除:delete from table1 where
     范围更新:update table1 set field1=value1 where
     范围查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
     */
    #pragma mark 增加
    - (IBAction)tapAdd:(id)sender
     {
        //添加一个person到表中
    //    NSString *sql = @"insert into person(name,age,tel) values('Bob','24','898989')";
    //    if ([self.manager runSqlWithString:sql]) {
    //        NSLog(@"添加成功!");
    //    }
        if ([self.name.text isEqualToString:@""]||[self.tel.text isEqualToString:@""]||[self.age.text isEqualToString:@""]) 
        {
            NSLog(@"姓名、年龄、电话都不能为空,请重新输入!");
        }else{
            NSString *sql = [NSString stringWithFormat:@"insert into person(name,age,tel) values('%@','%@','%@')",self.name.text,self.age.text,self.tel.text];
            NSLog(@"sql==== %@",sql);
    
            if ([self.manager runSqlWithString:sql])
            {
                NSLog(@"++++%@++++添加成功++++",self.name.text);
            }else{
                NSLog(@"----%@----添加失败----",self.name.text);
            }
        }
    }
    
    #pragma mark 查询
    - (IBAction)tapFind:(id)sender
     {
        //查询所有
        NSString *sql = @"select * from person";
        NSArray *result = [self.manager getDataWithString:sql];
        NSLog(@"result = %@",result);
    }
    
    #pragma mark 更新
    - (IBAction)tapUpdate:(id)sender 
    {
        NSString *sql = @"update person set name='Tom' where person_id=2";
    
        if ([self.manager runSqlWithString:sql]) 
        {
            NSLog(@"更新成功!");
        }
    }
    
    #pragma mark 删除
    - (IBAction)tapDelete:(id)sender 
    {
    //    NSString *sql = @"delete from person where person_id=2";
    //    if ([self.manager runSqlWithString:sql]) {
    //        NSLog(@"删除成功!");
    //    }
        
        if ([self.person_id.text isEqualToString:@""]) {
            NSLog(@"只能通过person_id进行删除!");
        }else{
            NSString *sql = [NSString stringWithFormat:@"delete from person where person_id=%@",self.person_id.text];
            if ([self.manager runSqlWithString:sql]) {
                NSLog(@"删除成功!");
            }else{
                NSLog(@"删除失败!");
            }
        }
    }
    

    SQLiteManager.m代码

    - (instancetype)init
    {
        self = [super init];
        if (self)
         {
            //1.获取沙盒路径NSHomeDirectory,为数据库提供路径
            NSString *path = [NSString stringWithFormat:@"%@/Documents/iOS.panzz.db",NSHomeDirectory()];
            NSLog(@"%@",path);
    
            //2.初始化fmdb,并且指定路径
            self.fmdb = [[FMDatabase alloc]initWithPath:path];
    
            //3.打开数据库
            if ([self.fmdb open]) {
                //4.如果沙盒中已经有table,则不再创建,否则创建table。
                //"前加反斜杠,当做普通字符处理
                NSString *sql = @"CREATE TABLE \"Person\" (\"person_id\" INTEGER PRIMARY KEY AUTOINCREMENT, \"name\" TEXT, \"age\" TEXT, \"tel\" TEXT)";
                //执行创建语句
                [self runSqlWithString:sql];
            }else{
                NSLog(@"打开数据库失败!");
            }
            
        }
        return self;
    }
    
    - (BOOL)runSqlWithString:(NSString *)sql
    {
        //执行更新的方法
        if ([self.fmdb executeUpdate:sql])
        {
            return YES;
        }else{
            return NO;
        }
    }
    
    //查询方法
    - (NSArray *)getDataWithString:(NSString *)sql
    {
        NSMutableArray *marr = [NSMutableArray array];
        FMResultSet *set = [self.fmdb executeQuery:sql];
    
        while (set.next) 
        {
            //在此方法中将查询结果一一添加到数组中
            NSDictionary *dic = [set resultDictionary];
            [marr addObject:dic];
        }
    
        return [NSArray arrayWithArray:marr];
    }
    

    6、归档、解档方法介绍

    //将自定义的类对象进行归档 (写)
    
        //1.可变数据
        NSMutableData* data = [[NSMutableData alloc]init];
    
        //2.归档对象
        Person* person = [[Person alloc]initWithName:@"Jackey" age:@20];
    
        //3.编码
        NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
        [archiver encodeObject:person forKey:@"person"];
    
    //    4.编码结束
        [archiver finishEncoding];
    
    //    5.写入文件
        NSString* docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        NSString* filePath = [docPath stringByAppendingPathComponent:@"archiving"];
        [data writeToFile:filePath atomically:YES];
        
     //    将自定义的类对象进行解档 (读)
    
        //1.从文件中读取到数据(NSData)
        NSData*  readData = [NSData dataWithContentsOfFile:filePath];
    
        //2.创建NSKeyedUnarchiver对象
        NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:readData];
    
        //3.对数据进行解码操作
        Person* p =  [unarchiver decodeObjectForKey:@"person"];
    
        //4.完成解码操作
        [unarchiver finishDecoding];
    

    相关文章

      网友评论

          本文标题:本地存取、本地存储

          本文链接:https://www.haomeiwen.com/subject/ztmwbttx.html