• IOS数据本地存储的四种方式--


    注:借鉴于:http://blog.csdn.net/jianjianyuer/article/details/8556024

          在IOS开发过程中,不管是做什么应用,都会碰到数据保存问题。将数据保存到本地,能够让程序更加流畅,不会出现让人厌恶的菊花状,使得用户的体验更好。下面是介绍数据保存的方式

     

     

    第一、NSKeyedArchiver:采用归档的形式来保存数据。(归档——解档)———大量数据和频繁读写不合适使用

      1、归档器的作用是将任意的对象集合转换为字节流。这听起来像是NSPropertyListSerialization类采用的过程,但是它们之间有一个重要的区别。属性列表序列化只能转换一个有限集合的数据类型(大多是数量类型),而归档可以转换任意的OC对象、数据类型、数组、结构、字符串以及更多其他类型。

      2、Foundatio框架支持两种归档器。顺序归档和基于键的归档。基于键的归档器更加灵活,是应用程序开发中推荐使用的归档器 。

      3、一个面向对象程序在运行的时候,一般都创建了一个复杂的对象关系图,经常需要把这样一个复杂的对象关系图表示成字节流,这样的过程叫做          Archiving.

      4、而当从字节流中重新恢复对象关系图的过程叫做unarchive。

      5、NSCoder是archivie字节流的抽象类。

      6、对一个对象归档需要满足的条件是:该对象的类必须实现NSCoding协议

    归档、

    -(int)create:(Note *)model
    
    {
    
        NSString *homeDictionary = NSHomeDirectory();
    
        NSString *path = [homeDictionary stringByAppendingPathComponent:FILE_NAME];
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
    
        
    
        BOOL isexists = [fileManager fileExistsAtPath:path];
    
        NSMutableArray *array = [[NSMutableArray alloc] init];
    
        [array addObject:model];
    
       
    
        //archive归档
    
        NSMutableData *theData = [NSMutableData data];
    
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];
    
        [archiver encodeObject:array forKey:ARCHIVE_KEY];
    
        [archiver finishEncoding];
    
        
    
        [theData writeToFile:path atomically:YES];
    
    //    [array writeToFile:path atomically:YES];
    
        
    
        return 0;
    
     
    
    }
    

    解档、

    -(NSMutableArray *)findAll
    
    {
    
        NSString *homeDictionary = NSHomeDirectory();
    
        NSString *path = [homeDictionary stringByAppendingPathComponent:FILE_NAME];
    
        NSMutableArray *listData = [[NSMutableArray alloc] init];
    
        NSData *theData = [NSData dataWithContentsOfFile:path];
    
        
    
        if([theData length]>0)
    
        {
    
            NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];
    
            listData = [archiver decodeObjectForKey:ARCHIVE_KEY];
    
            [archiver finishDecoding];
    
        }
    
        return listData;
    
    }
    

    第二、NSUserDefaults

     

    //自动登陆用到的
    
     
    
    +(id)configForKey:(NSString *)key
    
    {
    
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        return [defaults objectForKey:key];
    
    }
    
    //写入内容
    
    +(void)setLoginConfig:(id)value forKey:(NSString *)key
    
    {
    
        NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    
        [user setObject:value forKey:key];
    
        [user synchronize];   //及时强制写入
    
    }
    
     
    
    //读出内容
    
    +(NSString *)getLoginConfig:(NSString *)key
    
    {
    
        NSString *s = [Globle  configForKey:key];
    
        if(s==nil)
    
        {
    
            return @"";
    
        }
    
        return s;
    
     
    
    }
    

     

    第三、write写入磁盘

    第一步:获得文件即将保存的路径:

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask,YES);//使用C函数NSSearchPathForDirectoriesInDomains来获得沙盒中目录的全路径。该函数有三个参数,目录类型、he domain mask、布尔值。其中布尔值表示是否需要通过~扩展路径。而且第一个参数是不变的,即为NSSearchPathDirectory 。在IOS中后两个参数也是不变的,即为:NSUserDomainMask 和 YES。
    NSString *ourDocumentPath =[documentPaths objectAtIndex:0];

    还有一种方法是使用NSHomeDirectory函数获得sandbox的路径。具体的用法为:

    NSString *sandboxPath = NSHomeDirectory();
    // Once you have the full sandbox path, you can create a path from it,但是不能在sandbox的本文件层上写文件也不能创建目录,而应该是此基础上创建一个新的可写的目录,例如Documents,Library或者temp。
    NSString *documentPath = [sandboxPath
                stringByAppendingPathComponent:@"Documents"];//将Documents添加到sandbox路径上,具体原因前面分析了!

    这两者的区别就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因为该文件目录可能在未来发送的系统上发生改变。

     

    第二步:生成在该路径下的文件:

    NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件名

    第三步:往文件中写入数据:

    [data writeToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName

     

    最后:从文件中读出数据:

    NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据

    第四、SQLite数据库

     
    
    @interface BaseViewController ()
    
    {
    
        sqlite3 *sqlDataBase;
    
    }
    
    @end
    
     
    
    @implementation BaseViewController
    
     
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    
    {
    
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    
        if (self) {
    
            // Custom initialization
    
        }
    
        return self;
    
    }
    
     
    
    - (void)viewDidLoad
    
    {
    
        [super viewDidLoad];
    
        if ([self createOrOpen:@"test.db"]) {
    
    //        [self createUserTable:sqlDataBase];
    
    //        [self insertMBkey:nil];
    
            NSMutableArray *s = [NSMutableArray new];
    
            [self GetList:s];
    
            NSLog(@"%@",s);
    
        }else
    
        {
    
            NSLog(@"FAIL");
    
        }
    
    }
    
    /**
    
     *该函数主要打开数据库myDataBase.sql,如果该数据库不存在,则进行创建
    
     *打开或者创建成功返回yes,否则返回false,参数dbName是数据库的名称
    
     **/
    
    -(BOOL)createOrOpen:(NSString *)dbName
    
    {
    
        //获取用户域覆径信息
    
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocuemntDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
    
        /**
    
         *Users/admin/Library/Application Support/iPhone Simulator/7.1/Applications/8E23557E-AAA6-471A-AAFE-E036BF1B7E4C/Library/Documentation
    
         *判断用户域是否有数据库dbNmae
    
         */
    
        NSString *path = [documentsDirectory stringByAppendingPathComponent:dbName];
        NSFileManager *fileManageer = [NSFileManager defaultManager];
        //如果用户域内有该数据库,则返回yes,否则返回NO
        BOOL find = [fileManageer fileExistsAtPath:path];
        if(find)   //对找到进行处理,如果找到了,并且打开了,则返回yes
        {
            //打开该数据库,如果打开失败,则返回NO,否则返回yes
            if(sqlite3_open([path UTF8String], &sqlDataBase)!= SQLITE_OK)
               {
                   //关闭sqlDataBase,实际是释放了它
    
                   sqlite3_close(sqlDataBase);
    
                   return NO;
               }
               return YES;
        }
      NSLog(@"%d",sqlite3_open([path UTF8String], &sqlDataBase));
             //创建数据库,创建返回yes,并且打开数据库,否则返回NO
        if(sqlite3_open([path UTF8String], &sqlDataBase)==SQLITE_OK)
        {
           return YES;
        }else
        {
         //关闭sqlDataBase,实际是释放了它
            sqlite3_close(sqlDataBase);
            return NO;
        }
        return NO;
    }
    //在打开的数据库中创建表,其中sqldb为成功打开的数据库的sqlite3对象
    -(BOOL)createUserTable:(sqlite3 *)sqlDataBas
    
    {
    
        //设置sql语句
    
        char *sql = "create table user(id integer primary key, name text, address text, imageData BLOB, imageLen integer)";
    
        sqlite3_stmt *statement;  //这个相当于ODBC的Command对象,用于保存编译好的SQL语句
    
        //进行预处理,预处理失败返回NO
    
        if(sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, nil)!=SQLITE_OK)
    
        {
    
            return NO;
    
        }
    
        //预处理成功,进行执行创建操作
    
        int success = sqlite3_step(statement);
    
        sqlite3_finalize(statement);
    
        if(success !=SQLITE_DONE)
    
        {
    
            return NO;
    
        }
    
        return YES;
    
        
    
        
    
    }
    
    //向表中插入数据
    
    -(void)insertMBkey:(NSString *)key
    
    {
    
        BOOL isOK = NO;
    
        sqlite3_stmt *statement;
    
        static char *sql = "INSERT INTO user VALUES ('1', 'Bill', '河南', 'ssss','2')";
    
        int success = sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, NULL);
    
        if(success !=SQLITE_OK)
    
        {
    
            isOK = NO;
    
        }else
    
        {
    
            sqlite3_bind_text(statement, 1, [key UTF8String], -1, SQLITE_TRANSIENT);
    
            success = sqlite3_step(statement);
    
            sqlite3_finalize(statement);
    
        }
    
        
    
        if(success ==SQLITE_ERROR)
    
        {
    
            isOK = NO;
    
        }else
    
        {
    
            isOK=YES;
    
        }
    
        
    
        return;
    
    }
    
    //查询数据
    
    -(void)GetList:(NSMutableArray *)KeysList
    
    {
    
        BOOL  isOK = NO;
    
        sqlite3_stmt *statement;
    
        static char *sql = "select id,address from user";
    
        int success = sqlite3_prepare_v2(sqlDataBase, sql, -1, &statement, NULL);
    
        if(success !=SQLITE_OK)
    
        {
    
            isOK = NO;
    
        }else
    
        {
    
            //查询结果集中一条一条地遍历所有记录,这里的数字对应的时列值
    
            while (sqlite3_step(statement)==SQLITE_ROW) {
    
                int kid = sqlite3_column_int(statement, 0);
    
                char *key = (char  *)sqlite3_column_text(statement, 1);
    
                UserInfo *userModel = [[UserInfo alloc] init];
    
            
    
                    userModel.userId =kid;
    
                if (key) {
    
                  userModel.userAddress = [NSString stringWithUTF8String:key];
    
                }
    
                    [KeysList addObject:userModel];
    
                sqlite3_finalize(statement);
    
            }
    
            NSLog(@"%@",KeysList);
    
            if(success==SQLITE_ERROR)
    
            {
    
                isOK = NO;
    
            }else
    
            {
    
                isOK = YES;
    
            }
    
            return;
    
        }
    
     
    
    }
    
     
    

     

  • 相关阅读:
    主成分分析(PCA)原理详解
    局部敏感哈希(Locality-Sensitive Hashing, LSH)方法介绍
    RSA算法原理(二)
    RSA算法原理(一)
    对倾斜的图像进行修正——基于opencv 透视变换
    GeoHash核心原理解析
    303. Range Sum Query
    325. Maximum Size Subarray Sum Equals k
    30. Substring with Concatenation of All Words
    76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/zhanggui/p/3927986.html
Copyright © 2020-2023  润新知