iOS开发之数据持久化(iOS中常用的四种数据存储方式)

本文介绍了iOS中四种常用的数据存储方式:属性列表(NSUserDefaults)、对象归档(NSKeyedArchiver)、SQLite数据库和Core Data。对于每种方式,分别阐述了其使用方法和特点。NSUserDefaults适用于简单数据存储,对象归档适合小量数据,SQLite提供灵活的数据库操作,而Core Data则通过抽象SQL简化数据管理。

(1)属性列表(NSUserDefaults)

NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。

存储

//存储int类型
[[NSUserDefaults standardUserDefaults] setInteger:123 forKey:@"userID"];
//存储string类型
[[NSUserDefaults standardUserDefaults] setObject:@"王伟楷" forKey:@"name"];

读取

//取出int类型并赋值给uuid
NSInteger uuid = [[NSUserDefaults standardUserDefaults] integerForKey:@"userID"];
//取出string类型并赋值给name
NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"name"];

(2)对象归档(NSKeyedArchiver

遵循<NSCoding>协议

实现- (void) encodeWithCoder:(NSCoder *)encoder 与 -(void)initWithCoder:(NSCoder *)encoder 这两个方法,前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码

同时,建议对象也同时实现NSCopying协议,该协议允许复制对象,要实现NSCopying协议须实现 -(id)copyWithZone:(NSZone *)zone 方法 。

缺点:归档的形式来保存数据,只能一次性归档保存以及一次性解压。所以只能针对小量数据,而且对数据操作比较笨拙,即如果想改动数据的某一小部分,还是需要解压整个数据或者归档整个数据。

首先对于需要归档的对象的类进行配置

#import <Foundation/Foundation.h>

@interface Save : NSObject<NSCoding>
@property (nonatomic, copy) NSString *name;
@end
#import "Save.h"

@implementation Save

//告诉系统怎么对对象进行编码
- (void)encodeWithCoder:(NSCoder *)aCoder;
{
    // 这里放置需要持久化的属性,
    [aCoder encodeObject:self.name forKey:@"name"];
}

//告诉系统怎么对对象进行解码
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if(self = [self init])
    {
        //  这里务必和encodeWithCoder方法里面的内容一致,不然会读不到数据
        self.name = [aDecoder decodeObjectForKey:@"name"];
    }
    return self;
}
@end

之后Save类创建的对象即可进行归档了。

获取文件存放的地址

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
//“1234567”为存放的文件名
NSString *file = [path stringByAppendingPathComponent:@"1234567"];

给文件赋值,并把文件存入到file指定的地方中去

self.save = [[Save alloc] init];
self.save.name = [NSString stringWithFormat:@"王伟楷"];
[NSKeyedArchiver archiveRootObject:self.save toFile: file];

文件取值并赋予对象

//首先先判断文件是否存在,存在的话才去取值
if([[NSFileManager defaultManager] fileExistsAtPath:file])
{
    self.save = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
}

(3)sqlite3

使用sqlite3其实和其他语言使用数据库差不多,主要是以为步骤:

  1. 从项目的build phases中的link binary with libraries 中添加包 lisqlite3.dylib或者lisqlite3.0.dylib
  2. 项目头文件要加上 #import "sqlite3.h"
  3. 打开数据库
  4. 编写数据库语句,之后即可进行增删改查了。

打开数据库的代码

    //db是数据库的句柄,要对数据库进行增删改查都需要它
    sqlite3 *db;
    //获得数据库文件的路径
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    NSString *file = [path stringByAppendingPathComponent:@"student.sqlite"];
    //将object-c转化为c
    const char *filename = [file UTF8String];
    //如果文件不存在则创建,文件存在则打开
    int result = sqlite3_open(filename, &db);
    //打开成功与失败的判断
    if (result == SQLITE_OK)
    {
        NSLog(@"成功打开数据库");
    }
    else
    {
        NSLog(@"打开数据库失败");
    }
当打开成功,就可以进行数据库表格的创建了
    //定义一个存储错误类型的
    char *errorMsg;
    //编写数据库语句,创建一个表格,包括id,name,age
    const char  *createSQL="CREATE TABLE IF NOT EXISTS t_students (id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL,age integer NOT NULL);";
    //执行数据库语句
    result = sqlite3_exec(db, createSQL, NULL, NULL, &errorMsg);
    if (result == SQLITE_OK)
    {
        NSLog(@"表格创建成功");
    }
    else
    {
        NSLog(@"表格创建失败");
    }

对数据库进行增加操作(注:增删改用的代码其实差不多一样的,只是数据库语句不一样罢了)

    //为数据库添加4条记录
    for (int i=0; i<4; i++)
    {
        NSString *name = [NSString stringWithFormat:@"伟楷%d",i];
        int age = i;
        NSString *sql=[NSString stringWithFormat:@"INSERT INTO t_students (name,age) VALUES ('%@',%d);",name,age];
        //2.执行SQL语句
        char *errmsg=NULL;
        sqlite3_exec(db, sql.UTF8String, NULL, NULL, &errmsg);
        if (errmsg)
        {//如果有错误信息
            NSLog(@"插入数据失败--%s",errmsg);
        }
        else
        {
            NSLog(@"插入数据成功");
        }
    }

对数据库进行删除操作

    NSString *delSql=[NSString stringWithFormat:@"DELETE FROM t_students WHERE age == 0;"];
    //执行SQL语句
    char *delErrmsg=NULL;
    sqlite3_exec(db, delSql.UTF8String, NULL, NULL, &delErrmsg);
    if (delErrmsg)
    {//如果有错误信息
        NSLog(@"删除数据失败--%s",delErrmsg);
    }
    else
    {
        NSLog(@"删除数据成功");
    }
对数据库进行修改操作

    NSString *UpdateSql=[NSString stringWithFormat:@" update t_students set name='王伟楷' where age=2;"];
    //2.执行SQL语句
    char *UpdateErrmsg=NULL;
    sqlite3_exec(db, UpdateSql.UTF8String, NULL, NULL, &UpdateErrmsg);
    if (UpdateErrmsg)
    {//如果有错误信息
        NSLog(@"修改数据失败--%s",UpdateErrmsg);
    }
    else
    {
        NSLog(@"修改数据成功");
    }
查询数据库

    const char *sql="SELECT id,name,age FROM t_students WHERE age<20;";
    sqlite3_stmt *stmt=NULL;
    //进行查询前的准备工作
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL)==SQLITE_OK)
    {
        
        //SQL语句没有问题
        NSLog(@"查询成功");
        //每调用一次sqlite3_step函数,stmt就会指向下一条记录
        while (sqlite3_step(stmt)==SQLITE_ROW)
        {
            //找到一条记录
            //取出数据
            //(1)取出第0列字段的值(int类型的值)
            int ID=sqlite3_column_int(stmt, 0);
            //(2)取出第1列字段的值(text类型的值)
            const unsigned char *name=sqlite3_column_text(stmt, 1);
            //(3)取出第2列字段的值(int类型的值)
            int age=sqlite3_column_int(stmt, 2);
            //NSLog(@"%d %s %d",ID,name,age);
            printf("%d %s %d\n",ID,name,age);
        }
    }
    else
    {
       NSLog(@"查询失败");
    }

记得最后使用完数据库要关闭数据库

    sqlite3_close(db);

(4)core data

Core Data本质上是使用SQLite保存数据,但是它不需要编写任何SQL语句。

添加CoreData框架

导入#import<CoreData/CoreData.h>

必须了解的6个对象:

  • NSManagedObjectContext (管理对象,上下文,持久性存储模型对象)
  • NSManagedObjectModel (被管理的数据模型,数据结构)
  • NSPersistentStoreCoordinator (连接数据库的)
  • NSManagedObject (被管理的数据记录)
  • NSFetchRequest (数据请求)
  • NSEntityDescription (表格实体结构)

然后具体的操作可以看以下这篇文章

http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值