zoukankan      html  css  js  c++  java
  • 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协议

    归档、

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    -(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;
     
      
     
    }

    解档、

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    -(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

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    //自动登陆用到的
     
      
     
    +(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数据库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    @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");
     
        }
     
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    /**
     
     *该函数主要打开数据库myDataBase.sql,如果该数据库不存在,则进行创建
     
     *打开或者创建成功返回yes,否则返回false,参数dbName是数据库的名称
     
     **/
     
    -(BOOL)createOrOpen:(NSString *)dbName
     
    {
     
        //获取用户域覆径信息
     
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectoryNSUserDomainMaskYES);
     
        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;
     
        }
     
      
     
    }
    如果一件事情你觉得难的完不成,你可以把它分为若干步,并不断寻找合适的方法。最后你发现你会是个超人。不要给自己找麻烦,但遇到麻烦绝不怕,更不要退缩。 电工查找电路不通点的最快方法是:分段诊断排除,快速定位。你有什么启示吗? 求知若饥,虚心若愚。 当你对一个事情掌控不足的时候,你需要做的就是“梳理”,并制定相应的规章制度,并使资源各司其职。
  • 相关阅读:
    jmeter响应结果乱码问题
    JMeter 脚本请求错误 HTTP Status 415 的解决
    使用fiddler进行genymotion安卓虚拟机手机抓包
    Android模拟器Genymotion安装使用教程详解
    java基础-数组
    Qt类继承图
    Linux-磁盘管理小结
    User and User Groups in Linux
    Qt5.3编译错误——call of overloaded ‘max(int int)’is ambiguous
    i++ and ++i efficiency
  • 原文地址:https://www.cnblogs.com/wvqusrtg/p/4497327.html
Copyright © 2011-2022 走看看